关于RandomAccess 接口

RamdomAccess接口是一个声明接口,接口内并没有声明任何的方法。
该接口只是为了标示实现了该接口的类是否推荐随机访问的遍历方式。
在实现了List 的接口的类中,有 LinkedList 和 ArrayList,其中ArrayList 实现了 RandomAccess 接口,而 LinkedList 没有。它们之间有什么不同呢?

      // ArrayList
        int num = 5000000;
        List<Integer> arrayList = new ArrayList<Integer>(num);
        for(int i=0;i<num ;i++){
          arrayList.add(1);
        }
        long time1 =System.currentTimeMillis();
        for (int i = 0, size = arrayList.size(); i < size; i++) {
            arrayList.get(i);
        }
        long time2 = System.currentTimeMillis();
        System.out.println(time2-time1); //34
        for (Integer integer : arrayList) {
        }
        long time3 = System.currentTimeMillis();
        System.out.println(time3-time2);//158
        //LinkedList
        List<Integer> linkedList = new LinkedList<Integer>();
        for (int i = 0, size = arrayList.size(); i < size; i++) {
          linkedList.add(i);
        }
        long time4 = System.currentTimeMillis();
        for (Integer integer : linkedList) {
        }
        long time5 = System.currentTimeMillis();
        System.out.println(time5-time4);//65
        for (int i = 0; i < num/200; i++) {  //这里除以200吧,要不然真的很久。
          linkedList.get(i);
        }
        long time6 = System.currentTimeMillis();
        System.out.println(time6-time5);//1449

结果会发现,声明了 RandomAccess 接口的 ArrayList 用顺序取值来遍历要比迭代器的方式要快。
而没有声明 RandomAccess 接口的 LinkedList 则迭代器遍历要比顺序取值快很多很多。
Java中的foreach语法是iterator(迭代器)的变形用法。但迭代器是需要知道两个相邻元素之间的关系的,不然怎么提供hasNext的支持呢?就是因为上一个元素要判断下一个元素是否存在的这种关系,违背了ArrayList随机存取的特性,所以在ArrayList 中用迭代器要比顺序遍历要慢。
注:foreach(Integer i : arrayList)  编译再反编译后得到下句:
for (Iterator localIterator1 = arrayList.iterator(); localIterator1.hasNext(); localInteger1 = (Integer)localIterator1.next());
而LinkedList 在随机访问时,它需要沿着双向链表去找到对应位置的元素,其效率较之ArrayList 内在实现的数组下标取元素访问,要低得多。
最后:RandomAccess 接口的声明与否全凭自觉。就foreach 而言,JDK似乎没有对它进行优化。
发表于 30/08/2013 , 11:39 于分类 .

reeoo.com - web design inspiration

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注