RandomAccess 接口的作用

RandomAccess 接口的作用

 

1、简介

         RandomAccess 接口是一个空接口,只是一个标记接口,用以标记实现的List集合具备快速随机访问的能力。那么什么是随机访问的能力呢?其实很简单,随机访问就是随机的访问List中的任何一个元素。所有的List实现都支持随机访问的,只是基于基本结构的不同,实现的速度不同罢了,这里的快速随机访问,那么就不是所有List集合都支持了。

  • ArrayList:基于数组实现,天然带下标,可以实现常量级的随机访问,复杂度为O(1)。
  • LinkedList:基于链表实现,随机访问需要依靠遍历实现,复杂度为O(n)。
public interface RandomAccess { }

二者的差距显而易见,所以ArrayList具备快速随机访问功能,而LinkedList没有。我们也能看到:

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable {}

 

public class LinkedList<E>
    extends AbstractSequentialList<E>
    implements List<E>, Deque<E>, Cloneable, java.io.Serializable
{}

 

2、测试

2.1、实现了 RandomAccess  ArrayList

  public static void main(String[] args) {
        ArrayList<Integer> arrayList = new ArrayList<>();
        for (int i = 0; i < 500000; i++) {
            arrayList.add(i);
        }
        long s = System.currentTimeMillis();
        for (int i = 0; i < arrayList.size(); i++) {
            Integer integer = arrayList.get(i);
        }
        long e = System.currentTimeMillis();
        System.out.println("实现了RandomAccess的ArrayList采用fori的遍历用时:" + (e - s));
        long s2 = System.currentTimeMillis();
        Iterator<Integer> iterator = arrayList.iterator();
        while (iterator.hasNext()) {
            Integer next = iterator.next();
        }
        long e2 = System.currentTimeMillis();
        System.out.println("实现了RandomAccess的ArrayList采用iterator的遍历用时:" + (e2 - s2));
    }

测试结果:

 

2.2、没有实现 RandomAccess的 LinkedList

 public static void main(String[] args) {
        LinkedList<Integer> linkedList = new LinkedList<>();
        for (int i = 0; i < 50000; i++) {
            linkedList.add(i);
        }
        long s = System.currentTimeMillis();
        for (int i = 0; i < linkedList.size(); i++) {
            Integer integer = linkedList.get(i);
        }
        long e = System.currentTimeMillis();
        System.out.println("没有实现RandomAccess的LinkedList采用fori的遍历用时:" + (e - s));
        long s2 = System.currentTimeMillis();
        Iterator<Integer> iterator = linkedList.iterator();
        while (iterator.hasNext()) {
            Integer next = iterator.next();
        }
        long e2 = System.currentTimeMillis();
        System.out.println("没有实现RandomAccess的LinkedList采用iterator的遍历用时:" + (e2 - s2));
    }

测试结果:

 

3、总结
         ArrayList用for循环遍历比iterator迭代器遍历快,LinkedList用iterator迭代器遍历比for循环遍历快,所以说,当我们在做项目时,应该考虑到List集合的不同子类采用不同的遍历方式,能够提高性能!那怎么判断出接收的List子类是ArrayList还是LinkedList呢? 这时就需要用 instanceof 来判断List集合子类是否实现RandomAccess接口!

  public void loop(List list) {
        if (list instanceof RandomAccess) {
            // for循环
            System.out.println("采用for循环遍历");
            for (int i = 0; i < list.size(); i++) {
                System.out.println(list.get(i));
            }
        } else {
            // 迭代器
            System.out.println("采用迭代器遍历");
            Iterator it = list.iterator();
            while (it.hasNext()) {
                System.out.println(it.next());
            }
        }
    }

 

posted @ 2023-04-26 11:04  邓维-java  阅读(398)  评论(0)    收藏  举报