Java集合類:"隨機訪問" 的RandomAccess接口
引出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, a
List
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接口