大佬理解->Java集合之ArrayList
存放的元素有序 |
---|
元素不唯一(可以重複) |
隨機存取快 |
插入刪除元素慢 |
非執行緒安全 |
底層初始化,使用一個Object型別的空物件陣列,初始長度為0;
原始碼
//Object型別物件陣列參照
transient Object[] elementData;
//預設空的Object陣列
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
//範例化時,將Object型別物件陣列參照 指向 預設空的Object陣列
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
首次新增元素,自動進行擴容,預設擴充容量是10(陣列的長度,也就是集合存放元素的個數);
原始碼
//如果是第一次新增元素
public boolean add(E e) {
//private int size; //size = 0;
//呼叫ensureCapacityInternal(int minCapacity)方法
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
//minCapacity = 1;
private void ensureCapacityInternal(int minCapacity) {
//呼叫calculateCapacity(Object[] elementData, int minCapacity)方法
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
private static int calculateCapacity(Object[] elementData, int minCapacity) {
//判斷是不是預設空的Object陣列
//如果是進入選擇一個陣列容量
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
//private static final int DEFAULT_CAPACITY = 10;
//minCapacity = 1;
//所以第一次新增元素時,自動進行擴容,預設擴充容量是10
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
//當前一次擴容的陣列容量不足時(放滿10個元素,再想新增一個元素,容量不足),開始進行動態擴容;
//每次擴容,是之前一次擴容後的陣列容量的1.5倍(即:每次都在前一次陣列容量的基礎上,增加一半-右移1位);
//最大容量Integer.MAX_VALUE - 8,即2^31-8
//擴容方法
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length; //舊陣列的容量
int newCapacity = oldCapacity + (oldCapacity >> 1); //新陣列的容量 = 老陣列的容量+老陣列的一半(右移一位)
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0) //如果新陣列的容量大於最大值,將陣列的容量設定為Integer.MAX_VALUE - 8
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
//private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
基於多型建立ArrayList集合物件
List<Object> list = new ArrayList<>(); // 推薦
Collection collection = new ArrayList();
ArrayList arrayList = new ArrayList();
List<Integer> intList = new ArrayList<>(); //可以使用泛型,指定存放資料的型別
方法 | 說明 |
---|---|
add(Object obj) | 新增元素 |
add(int index, E element) | 指定下標新增元素 |
remove(int index) | 移除元素 |
get(int index)) | 獲取元素 |
size() | 集合元素個數 |
contains(Object o) | 是否包含某元素 |
isEmpty() | 集合是否為空 |
5.1 add(Object obj)
//新增元素方法:add(Object obj),每次新增元素都是自動新增到陣列的末尾,元素下標值從0開始,跟陣列一致;
//可以新增重複值;
//可以新增null值;
5.2 add(int index, E element)
//指定下標新增元素和刪除元素,執行效率比較低;
5.3 remove(int index)
// 根據下標刪除,如果重複,只能刪除第一個出現的;
5.4 get(int index))
// 獲取元素方法:get(下標值),只能通過下標取值;
//當存取下標值超出了集合元素的最大下標值,報下標越界異常:java.lang.IndexOutOfBoundsException
// 可用的下標值的範圍:最小值是0,最大值是集合元素的個數 - 1
5.5 size()
// 獲取集合中元素個數方法:size();
5.6 contains(Object o)
// 判斷list集合中,是否包含某個元素方法:contains(查詢元素值),返回true,代表存在,返回false,代表不存在;
5.7 isEmpty()
// 判斷list集合是否為空方法:isEmpty(),返回true代表沒有元素,空的,返回false,代表有元素,不是空的
// 底層就是通過集合中元素個數size == 0 判斷,所以也可以使用size() == 0判斷集合非空
原始碼
public boolean isEmpty() {
return size == 0;
}
5.8 clear()
//清空list集合方法:clear(),清除集合中的所有元素
原始碼
ublic void clear() {
modCount++;
// clear to let GC do its work
for (int i = 0; i < size; i++) //一次將陣列賦值為null;
elementData[i] = null;
size = 0; //設定陣列長度為0;
}
5.9 toArray()
// list集合一步轉換為陣列方法:toArray(),返回的是Object型別陣列
Arrays.asList(目標陣列)
String[] strArrays = {"奧迪", "賓士", "寶馬"};
List<String> strList1 = Arrays.asList(strArrays);
System.out.println(strList1); //[奧迪, 賓士, 寶馬]
List<String> strList = new ArrayList<>();
strList.add("Audi");
strList.add("Benz");
strList.add("Bmw");
strList.add("Audi");
//for迴圈
for (int i = 0; i < strList.size(); i++) {
System.out.println("汽車品牌:" + strList.get(i));
}
//迭代器
//Iterator迭代器,只能通過集合獲取,不可以重複使用,迭代結束,迭代器就失效,如果想再次使用,需要重新獲取
Iterator<String> iterator = strList.iterator();
// 迭代器遍歷,使用while,不知道其中元素個數
while(iterator.hasNext()){
System.out.println("汽車品牌:" + iterator.next());
}
執行結果:
汽車品牌:Audi
汽車品牌:Benz
汽車品牌:Bmw
汽車品牌:Audi
//Vector,底層資料結構是和ArrayList一致的,都是物件陣列,但是它的操作是執行緒安全的,每個方法都帶有synchronized同步;
// 預設初始容量是10,可以自定義,但是不能小於0,預設每次擴容是前一次容量的一倍,擴容的數量也是可以指定的,如果指定,每次都是在前一次基礎上擴容指定的數量