若是咱們用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, 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 爲例。
分別建立兩個方法,一個用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 接口確實是有這個效果。
固然,如今的語言和機器性能這麼高,兩種方式遍歷數據的性能差距幾乎能夠忽略不計,尤爲是數據量不大的狀況下。因此,我以爲,平常使用中不必過度追求哪一種方式好,按照本身的習慣來就行。