在java編程過程中,許多人慣使用并常用的的幾個類型莫過于String,ArrayList以及HashMap了,以至于并沒有關心過LinkedList及Hashtable等類型及它們的區別,致使寫出的程序看似漂亮但是并不高效。
現在我來分享下我了解的ArrayList和LinkedList的區別。從數據結構上看,顧名思義,ArrayList是實現了基于動態數組的結構,而LinkedList則是基于實現鏈表的數據結構。而兩種數據結構在程序上體現出來的優缺點在于增刪和改查的速率,就此,我們分別作出說明。
數據的更新和查找
ArrayList的所有數據是在同一個地址上,而LinkedList的每個數據都擁有自己的地址.所以在對數據進行查找的時候,由于LinkedList的每個數據地址不一樣,get數據的時候ArrayList的速度會優于LinkedList,而更新數據的時候,雖然都是通過循環循環到指定節點修改數據,但LinkedList的查詢速度已經是慢的,而且對于LinkedList而言,更新數據時不像ArrayList只需要找到對應下標更新就好,LinkedList需要修改指針,速率不言而喻
數據的增加和刪除
對于數據的增加元素,ArrayList是通過移動該元素之后的元素位置,其后元素位置全部+1,所以耗時較長,而LinkedList只需要將該元素前的后續指針指向該元素并將該元素的后續指針指向之后的元素即可。與增加相同,刪除元素時ArrayList需要將被刪除元素之后的元素位置-1,而LinkedList只需要將之后的元素前置指針指向前一元素,前一元素的指針指向后一元素即可。當然,事實上,若是單一元素的增刪,尤其是在List末端增刪一個元素,二者效率不相上下。
例
下面我們通過程序檢驗結果:
public static final int N = 50000;
static void getTime(List list) {
insertByPosition(list);
readByPosition(list);
updateByPosition(list);
deleteByPosition(list);
}
// 向list的指定位置插入N個元素,并統計時間
private static void insertByPosition(List list) {
long startTime = System.currentTimeMillis();
for (int i = 0; i < N; i++)
list.add(0, i);
long endTime = System.currentTimeMillis();
long interval = endTime - startTime;
System.out.println(getListName(list) + "插入" + N + "條數據耗時:" + interval
+ " ms");
}
//從list中讀取元素,并統計時間
private static void readByPosition(List list) {
long startTime = System.currentTimeMillis();
for (int i = 0; i < N; i++){
list.get(i);
}
long endTime = System.currentTimeMillis();
long interval = endTime - startTime;
System.out.println(getListName(list) + "查詢" + N + "條數據耗時:" + interval
+ "ms");
}
// 從list的隨機位置修改元素,并統計時間
private static void updateByPosition(List list) {
long startTime = System.currentTimeMillis();
int M = 40000;
for(int i=0;i<40000;i++){
int j = (int)(1+Math.random()*(40000-1+1));
list.set(j, "list");
}
long endTime = System.currentTimeMillis();
long interval = endTime - startTime;
System.out.println(getListName(list) + "隨機修改" + M + "條數據耗時" + interval
+ " ms");
}
// 從list的指定位置刪除N個元素,并統計時間
private static void deleteByPosition(List list) {
long startTime = System.currentTimeMillis();
// 刪除list第一個位置元素
for (int i = 0; i < N; i++)
list.remove(0);
long endTime = System.currentTimeMillis();
long interval = endTime - startTime;
System.out.println(getListName(list) + "刪除" + N + "條數據耗時" + interval
+ " ms");
}
//獲取list類型名稱
private static String getListName(List list) {
if (list instanceof LinkedList) {
return "LinkedList";
} else if (list instanceof ArrayList) {
return "ArrayList";
} else {
return "error";
}
}
public static void main(String[] args) {
getTime(new ArrayList());
getTime(new LinkedList());
}
然后在我本機的運行結果如下:
由此可見在程序執行過程中,對大量數據的增刪改查時就會面臨效率問題,所以對于ArrayList和LinkedList的選擇,多數情況下如果查詢操作較多ArrayList的效果更好.如果刪除,插入較多LinkedList的效果較好.當然,具體怎么用還看具體的需求.