Java集合框架(一)-ArrayList
大佬理解->Java集合之ArrayList
1、ArrayList的特點
存放的元素有序 |
---|
元素不唯一(可以重複) |
隨機訪問快 |
插入刪除元素慢 |
非執行緒安全 |
2、底層實現
底層初始化,使用一個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;
}
3、擴容
//當前一次擴容的數組容量不足時(放滿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;
}
4、ArrayList初始化
基於多態創建ArrayList集合對象
List<Object> list = new ArrayList<>(); // 推薦
Collection collection = new ArrayList();
ArrayList arrayList = new ArrayList();
List<Integer> intList = new ArrayList<>(); //可以使用泛型,指定存放數據的類型
5、常用方法
方法 | 說明 |
---|---|
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類型數組
6、數組轉換成集合
Arrays.asList(目標數組)
String[] strArrays = {"奧迪", "Benz", "寶馬"};
List<String> strList1 = Arrays.asList(strArrays);
System.out.println(strList1); //[奧迪, Benz, 寶馬]
7、遍歷
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
8、Vector(執行緒安全)
//Vector,底層數據結構是和ArrayList一致的,都是對象數組,但是它的操作是執行緒安全的,每個方法都帶有synchronized同步;
// 默認初始容量是10,可以自定義,但是不能小於0,默認每次擴容是前一次容量的一倍,擴容的數量也是可以指定的,如果指定,每次都是在前一次基礎上擴容指定的數量