1. 程式人生 > >Java集合類:"隨機訪問" 的RandomAccess接口

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

ble java集合 .get 同時 ++ linked loop pri strac

引出RandomAccess接口

如果我們用Java做開發的話,最常用的容器之一就是List集合了,而List集合中用的較多的就是ArrayList 和 LinkedList 兩個類,這兩者也常被用來做比較。因為最近在學習Java的集合類源碼,對於這兩個類自然是不能放過,於是乎,翻看他們的源碼,我發現,ArrayList實現了一個叫做 RandomAccess 的接口,而 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

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

 * @since 1.4
 */
public interface RandomAccess {
}

那麽這個接口是做什麽的?

標誌接口

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

public interface RandomAccess

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

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

同時,官網還特意說明了,如果是實現了這個接口的 List,那麽使用for循環的方式獲取數據會優於用叠代器獲取數據。

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 接口確實是有這個效果。

當然,現在的語言和機器性能這麽高,兩種方式遍歷數據的性能差距幾乎可以忽略不計,尤其是數據量不大的情況下。所以,我覺得,日常使用中沒必要過分追求哪種方式好,按照自己的習慣來就行。

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