今天來比較下ArrayList和LinkedList使用不同方式遍歷時的速度,網上有許多這方面的比較,但是還是實踐出真知嘛~
ArrayList
測試代碼如下:
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Scanner;
import java.util.concurrent.ConcurrentHashMap;
public class Main {
public static void main(String[] args) {
ArrayList<Integer> list1 = new ArrayList<>();
for(int i = 0; i < 10000000; i++) {
list1.add(i);
}
long start1 = System.currentTimeMillis();
for (int i = 0; i < list1.size(); i++) {
int val = list1.get(i);
}
long end1 = System.currentTimeMillis();
long start2 = System.currentTimeMillis();
for (int i : list1) {
int val = i;
}
long end2 = System.currentTimeMillis();
long start3 = System.currentTimeMillis();
Iterator<Integer> iterator = list1.iterator();
while (iterator.hasNext()) {
int val = iterator.next();
}
long end3 = System.currentTimeMillis();
System.out.println("ArrayList test:");
System.out.println("for cost:" + (end1 - start1));
System.out.println("foreach cost:" + (end2 - start2));
System.out.println("iterator cost:" + (end3 - start3));
}
}
首先在ArrayList中添加一千萬數據,然後分別用三種方式遍歷計時。運行結果大致如下,每次會稍有波動但是整體來說第一種方式最快,迭代器方式最慢。ArrayList的遍歷時間差別不大。
LinkedList
測試代碼如下:
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
public class Main {
public static void main(String[] args) {
List<Integer> list1 = new LinkedList<>();
for(int i = 0; i < 200000; i++) {
list1.add(i);
}
long start1 = System.currentTimeMillis();
for (int i = 0; i < list1.size(); i++) {
int val = list1.get(i);
}
long end1 = System.currentTimeMillis();
long start2 = System.currentTimeMillis();
for (int i : list1) {
int val = i;
}
long end2 = System.currentTimeMillis();
long start3 = System.currentTimeMillis();
Iterator<Integer> iterator = list1.iterator();
while (iterator.hasNext()) {
int val = iterator.next();
}
long end3 = System.currentTimeMillis();
System.out.println("LinkedList test:");
System.out.println("for cost:" + (end1 - start1));
System.out.println("foreach cost:" + (end2 - start2));
System.out.println("iterator cost:" + (end3 - start3));
}
}
由於for循環的方式實在太慢,將LinkedList長度改爲20萬。
測試結果如下:
可見對於LinkedList使用for循環遍歷,時間就長了好幾個量級,迭代器是最快的。
所以平時在遍歷較大的LinkedList絕對不能使用for循環方式。
究其原因,是因爲LinkedList基於鏈表實現,for循環情況下每一次循環都會去遍歷半個list,嚴重影響了遍歷的效率。
擴展
需要注意的是,LinkedList遍歷到某個元素需要刪除時,也要使用iterator.remove()
方法,而不是list.remove(s)
。後者會重新遍歷LinkedList來尋找滿足條件的元素。