Java集合類:"隨機訪問" 的RandomAccess接口

引出RandomAccess接口

若是咱們用Java作開發的話,最經常使用的容器之一就是List集合了,而List集合中用的較多的就是ArrayList 和 LinkedList 兩個類,這二者也常被用來作比較。由於最近在學習Java的集合類源碼,對於這兩個類天然是不能放過,因而乎,翻看他們的源碼,我發現,ArrayList實現了一個叫作 RandomAccess 的接口,而 LinkedList 是沒有的,java

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

打開源碼後,發現接口裏面什麼也沒有,這是個空的接口,而且是1.4才引入的dom

* @since 1.4
 */
public interface RandomAccess {
}

那麼這個接口是作什麼的?oop

標誌接口

經過官網的API,我才知道,原來這是一個標誌接口,下面引入一段官網的原文:性能

public interface RandomAccess學習

Marker interface used by List implementations to indicate that they support fast (generally constant time) random access.測試

這段話大概的意思就是說 RandomAccess 是一個標誌接口,代表實現這個這個接口的 List 集合是支持快速隨機訪問的。也就是說,實現了這個接口的集合是支持 快速隨機訪問 策略的。this

同時,官網還特地說明了,若是是實現了這個接口的 List,那麼使用for循環的方式獲取數據會優於用迭代器獲取數據。code

As a rule of thumb, aList implementation should implement this interface if, for typical instances of the class, this loop:接口

​ for (int i=0, n=list.size(); i < n; i++)
list.get(i);開發

​ for (Iterator i=list.iterator(); i.hasNext(); )
i.next();

下面作個測試吧,以ArrayList 爲例。

Demo測試

分別建立兩個方法,一個用for循環 get() 數據的方式遍歷集合,另外一個是用迭代器,分別返回所用的時間:

public static long arrayFor() {
    List<Integer> list = new ArrayList<Integer>();
    for (int i = 1; i <= 100000; i++) {
        list.add(i);
    }
    //開始時間
    long startTime = System.currentTimeMillis();

    for (int j = 0; j < list.size(); j++) {
        Object num = list.get(j);
    }

    //結束時間
    long endTime = System.currentTimeMillis();

    //返回所用時間
    return endTime-startTime;
}

public static long arrayIterator() {
    List<Integer> list = new ArrayList<Integer>();
    for (int i = 1; i <= 100000; i++) {
        list.add(i);
    }
    long startTime = System.currentTimeMillis();

    Iterator iterator = list.iterator();
    while (iterator.hasNext()){
        Object next = iterator.next();
    }

    long endTime = System.currentTimeMillis();

    return endTime-startTime;
}

接着,在mian方法中測試:

public static void main(String[] args) {
    long time1 = arrayFor();
    long time2 = arrayIterator();

    System.out.println("ArrayList for循環所用時間=="+time1);
    System.out.println("ArrayList 迭代器所用時間=="+time2);
}

運行程序,輸出結果

ArrayList for循環所用時間==2
ArrayList 迭代器所用時間==3

能夠看出,for循環遍歷元素時間上是少於迭代器的,證實RandomAccess 接口確實是有這個效果。

固然,如今的語言和機器性能這麼高,兩種方式遍歷數據的性能差距幾乎能夠忽略不計,尤爲是數據量不大的狀況下。因此,我以爲,平常使用中不必過度追求哪一種方式好,按照本身的習慣來就行。

相關文章
相關標籤/搜索