关于接口 RandomAccess

今天看到java.util.Collections这个工具类中的

 public static <T> void fill(List<? super T> list, T obj) {
        int size = list.size();
        if (size < FILL_THRESHOLD || list instanceof RandomAccess) { // 这一行
            for (int i=0; i<size; i++)
                list.set(i, obj);
        } else {
            ListIterator<? super T> itr = list.listIterator();
            for (int i=0; i<size; i++) {
                itr.next();
                itr.set(obj);
            }
        }
    }


上面代码中标识的一行, FILL_THRESHOLD 是25,就是说,如果要填充的目标List范围不是很大,那么就直接用上面的方式效率比较高,同时注意到   list instanceof RamdomAccess 这个代码,顺便翻到里面去瞅了一眼,RamdomAccess 接口是一个空接口,空接口的作用一般起到一个标识作用,比如:Serializable 接口。

RaomdomAccess接口里面的文档说明大致意思:给可以提供随机访问的List实现去标识一下,这样使用这个List的程序在遍历这种类型的List的时候可以有更高效率。仅此而已。

所以,我们在遍历List之前,可以用  if( list instanceof RamdomAccess ) 来标识一下,选择用哪种遍历方式。

测试代码:

package com.zslin.list.demo;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.RandomAccess;

//JDK中说的很清楚,在对List特别是Huge size的List的遍历算法中,
//    要尽量来判断是属于RandomAccess(如ArrayList)还是Sequence List (如LinkedList),
//    因为适合RandomAccess List的遍历算法,用在Sequence List上就差别很大,常用的作法就是:
//    要作一个判断:
//    if (list instance of RandomAccess) {
//        for(int m = 0; m < list.size(); m++){}
//    }else{
//        Iterator iter = list.iterator();
//        while(iter.hasNext()){}
//    }

/**
 *
 * @author WQ<br>
 * @version 创建时间:2017年6月18日 下午6:01:14<br>
 */
public class TestRandomAccess {
    // 初始化列表

    public static void initList(List list, int n) {
        for (int i = 0; i < n; i++) {
            list.add(i);
        }
    }

    // 使用循环进行对列表的迭代

    public static void traverseWithLoop(List list) {
        long starttime = 0;
        long endtime = 0;
        starttime = System.currentTimeMillis();
        for (int count = 0; count <= 1000; count++) {
            for (int i = 0; i < list.size(); i++) {
                list.get(i);
            }
        }
        endtime = System.currentTimeMillis();
        System.out.println("使用loop迭代一共花了" + (endtime - starttime) + "ms时间");

    }

    // 使用迭代器对列表进行迭代

    public static void traverseWithIterator(List list) {
        long starttime = 0;
        long endtime = 0;
        starttime = System.currentTimeMillis();
        for (int count = 0; count <= 1000; count++) {
            for (Iterator itr = list.iterator(); itr.hasNext();) {
                itr.next();
            }
        }
        endtime = System.currentTimeMillis();
        System.out.println("使用Iterator迭代一共花了" + (endtime - starttime) + "ms时间");
    }

    public static void traverse(List list) {

        long starttime = 0;
        long endtime = 0;
        if (list instanceof RandomAccess) {
            System.out.println("该list实现了RandomAccess接口");
            starttime = System.currentTimeMillis();
            for (int count = 0; count <= 1000; count++) {
                for (int i = 0; i < list.size(); i++) {
                    list.get(i);
                }
            }
            endtime = System.currentTimeMillis();
            System.out.println("迭代一共花了" + (endtime - starttime) + "ms时间");
        } else {
            System.out.println("该list未实现RandomAccess接口");
            starttime = System.currentTimeMillis();
            for (int count = 0; count <= 1000; count++) {
                for (Iterator itr = list.iterator(); itr.hasNext();) {
                    itr.next();
                }
            }
            endtime = System.currentTimeMillis();
            System.out.println("迭代一共花了" + (endtime - starttime) + "ms时间");
        }
    }

    public static void main(String[] args) {
        ArrayList arraylist = new ArrayList();
        LinkedList linkedlist = new LinkedList();
        initList(arraylist, 1000);
        initList(linkedlist, 1000);
        traverse(arraylist);
        traverse(linkedlist);
        traverseWithIterator(arraylist);
        traverseWithLoop(arraylist);
        traverseWithIterator(linkedlist);
        traverseWithLoop(linkedlist);
    }
}

运行结果如下:

该list实现了RandomAccess接口
迭代一共花了9ms时间
该list未实现RandomAccess接口
迭代一共花了10ms时间
使用Iterator迭代一共花了12ms时间
使用loop迭代一共花了7ms时间
使用Iterator迭代一共花了14ms时间
使用loop迭代一共花了396ms时间

以上。

时间: 2024-08-28 07:50:49

关于接口 RandomAccess的相关文章

Java集合类操作优化总结

清单 1.集合类之间关系 Collection├List│├LinkedList│├ArrayList│└Vector│ └Stack└SetMap├Hashtable├HashMap└WeakHashMap 本文讲的就是集合框架的使用经验总结,注意,本文所有代码基于 JDK7. 集合接口 Collection 接口 Collection 是最基本的集合接口,一个 Collection 代表一组 Object,即 Collection 的元素(Elements).一些 Collection 允许

转载的,讲解java.util的集合类

本文是转载的 http://www.ibm.com/developerworks/cn/java/j-lo-set-operation/index.html#ibm-pcon 在实际的项目开发中会有很多的对象,如何高效.方便地管理对象,成为影响程序性能与可维护性的重要环节.Java 提供了集合框架来解决此类问题,线性表.链表.哈希表等是常用的数据结构,在进行 Java 开发时,JDK 已经为我们提供了一系列相应的类来实现基本的数据结构,所有类都在 java.util 这个包里,清单 1 描述了集

Java集合(二):List列表

在上一节中,介绍了Java集合的总体情况.从这节開始,将介绍详细的类.这里不单单介绍类的使用方法.还会试图从源代码的角度分析类的实现.这一节将介绍List接口及实现类.即列表中的链表LinkedList和数组列表ArrayList. 1 List接口及抽象类 List接口扩展自Collection接口,这个接口设计了一些适合列表操作的方法.List是一个有序集合.元素能够加入到容器中某个特定的位置. 使用javac编译List.java源代码后,能够使用javap反编译源代码获得接口的详细信息.

ArrayList 浅析示例

1 package com.smbea.demo; 2 3 import java.util.ArrayList; 4 import java.util.Iterator; 5 import java.util.List; 6 7 /** 8 * 1.继承自接口 List.RandomAccess.Cloneable.Serializable: 9 * 2.实现自类 AbstractList: 10 * 3.元素有顺序: 11 * 4.增删操作由于要移动元素,故此增删比较慢: 12 * 5.查询

Java API学习笔记(一)

1. 不要重复初始化变量 默认情况下,调用类的构造函数时,java会把变量初始化成确定的值,所有的对象被设置成null,整数变量设置成0,float和double变量设置成0.0,逻辑值设置成false.当一个类从另一个类派生时,这一点尤其应该注意,因为用new关键字创建一个对象时,构造函数链中的所有构造函数都会被自动调用.这里有个注意,给成员变量设置初始值但需要调用其他方法的时候,最好放在一个方法比如initXXX()中,因为直接调用某方法赋值可能会因为类尚未初始化而抛空指针异常,如:publ

jdbc桥连接过程解析

读多少源码,便知自己有多无知! 想温习一下桥链接模式,然后觉得自己已然吃透了,因为自己写的博客,觉得还是应该更具体一些. 类似于这样的结构: 个人理解: 结构型模式 - 桥连接模式 概述: Bridge模式的应用场景 结构图: 桥接模式的优缺点 桥连接模式的应用实例 代码(其实读UML图要比代码还要一目了然) 参考/转自 便是一目了然了,觉得应该找个在Java中桥连接模式的实际应用,于是就找到了Jdbc连接. 于是,困惑的旅程开始了....... //加载及注册JDBC驱动程序 Class.fo

Java源码分析系列之ArrayList读后感

1.前言 在平时的开发中,Java集合一直是比较常用的.以前,对集合的掌握并不深入,仅简单的使用增删改查的相关方法.这个星期,抽时间反复的读了几遍ArrayList的源码,有了一些收获,写出来给自己,也希望对大家有帮助. 2.走进ArrayList 看一下ArrayList的声明和属性 声明: public class ArrayList<E> extends AbstractList<E>         implements List<E>, RandomAcces

ArrayList(jdk 1.7.0_80)

jdk1.7中有几个更新,List<Integer> l = new ArrayList();是允许的,更多的jdk1.7特性可参考:陈大大博客 http://blog.csdn.net/chenleixing/article/details/47802653. 看源码, 1 public class ArrayList<E> extends AbstractList<E> 2 implements List<E>, RandomAccess, Clonea

Java集合类总结 (五)

集合框架 为了避免进行不必要的随机访问操作,Java引入了一种标签接口RandomAccess, 这个接口没有任何方法,只是一个标签,用来标记一个集合是否应该进行随机访问操作: if (c instanceof RandomAccess) { use random access algorithm } else { use sequential access algorithm } Collection接口提供了很多基础的方法方便使用,而且框架中也提供了很多抽象类实现Collection接口中的