前言
現如今的Java程序員越來越多,學習者也越來越多。基本上使用Java的都會使用過HashSet、HashMap、ArrayList、LinkedList等集合,今天god-jiang就從源碼層面上粗略解讀一下ArrayList這個常用集合。
若是有寫得不好的地方或者有錯誤,請讀者提出,畢竟我也是一名菜雞。
1、ArrayList的介紹
ArrayList是一個容量能夠動態增長的動態數組。但是它和數組又不一樣,它繼承了AbstractList,實現了List、RandomAccess(隨機訪問)、Cloneable、Serializable接口。
2、ArrayList的構造函數
在JDK1.8的版本下,ArrayList有三個構造函數。分別是:
- ArrayList():構造一個初始容量爲10的空數組列表
- ArrayList(int initialCapacity):構造一個具有初始容量值的空數組列表
- ArrayList(Collection c):構造一個包含指定元素的數組列表
源碼如下:
3、ArrayList的add操作
在JDK1.8的版本里,add操作有兩種,一種是按順序一直添加,另一種是給定一個位置再添加。源碼如下:
就是進行add操作的時候,需要先進行ensureCapacityInternal操作,就是size+1判斷是否需要擴容了,如果不需要,則直接插入,然後size++。如果需要擴容,就會擴容到原來的1.5倍,源碼如下:
4、ArrayList的遍歷方式
給出ArrayList遍歷常用的三種方式:
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* @author god-jiang
* @date 2020/4/3 14:22
*/
public class ArrayList_Resource {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("李白");
list.add("露娜");
list.add("韓信");
//1、迭代器
Iterator<String> it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
System.out.println("================");
//2、for
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
System.out.println("================");
//3、for-each
for (String str : list) {
System.out.println(str);
}
}
}
肯定會有人問用哪個比較好,這裏我只能說博主經常使用的是第二種遍歷方式,因爲效率最高。爲啥效率最高,可以自己加入系統時間算時間差來比較得出。
5、ArrayList和LinkedList的區別(面試常問)
- 是否保證線程安全:ArrayList和LinkedList都是不同步的,也就是不保證線程安全;
- 底層數據結構:ArrayList底層使用的是Object數組;LinkedList底層使用的是雙向鏈表;
- 插入和刪除是否受元素位置影響:ArrayList採用數組存儲,所以插入和刪除元素的時間複雜度受元素的位置影響,爲O(N)。LinkedList採用鏈表存儲,所以插入和刪除元素的時間複雜度不受元素位置的影響,爲O(1);
- 是否支持快速隨機訪問:LinkedList不支持高速的隨機元素訪問,而ArrayList支持;
- 內存空間佔用:ArrayList的空間浪費主要體現在List列表的結尾會預留一定的容量空間,而LinkedList得空間花費體現在它得每一個元素都需要消耗比ArrayList更多的空間(因爲要存放直接前驅和後繼以及數據等)。
總結
今天的ArrayList源碼就講這麼多,還有一些remove操作和contains操作我就沒有寫出來,不是說它們不重要,而是我把相對重要和常問的點拿出來講一下。對ArrayList其他操作感興趣可以自己看看源碼,這個東西對你只會有好處而不會有壞處。
謝謝大家,有錯誤或者寫得不好的歡迎評論區評論或者私聊。