描述
ArrayList 現(xiàn)實了List接口,是一個順序容器,存放元素的順序和取出元素的順序是一樣的,內(nèi)部是用<mark style="box-sizing: border-box;">數(shù)組</mark>來實現(xiàn)的,<mark style="box-sizing: border-box;">可以存放null</mark>
成員屬性
private static final int DEFAULT_CAPACITY = 10; //默認容器長度
private static final Object[] EMPTY_ELEMENTDATA = {}; //空數(shù)組,也就是new ArrayList(0)
image.png
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; //也是空數(shù)組 new ArrayList()
[圖片上傳失敗...(image-f94dc8-1632339423811)]
transient Object[] elementData; //真正的用來保存元素的數(shù)組
private int size; //元素個數(shù)
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; //可以分配的最大元素個數(shù)
protected transient int modCount = 0; //被這個list內(nèi)容被修改的次數(shù),比如add,remove() 都會加+1,這個參數(shù)也是Fail-Fast機制時使用的,通過記錄modCount參數(shù)來實現(xiàn)。在面對并發(fā)的修改時,迭代器很快就會完全失敗,而不是冒著在將來某個不確定時間發(fā)生任意不確定行為的風(fēng)險
方法
add()
image.png
private void ensureCapacityInternal(int minCapacity) {
//這個if 只是在new ArrayList() 之后 add()就會進去
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);//默認 10 和1 比,當(dāng)然是10
}
ensureExplicitCapacity(minCapacity);//進去
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++; //發(fā)送修改 modCount+1
// overflow-conscious code
if (minCapacity - elementData.length > 0) // minCapacity 是否大于原來的容器長度,這個是關(guān)鍵判斷
grow(minCapacity); //擴容全靠它了了,哈哈
}
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); //大于則是Integer.MAX_VALUE
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity); //進行數(shù)組拷貝,yes yes yes
}
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
set()
public E set(int index, E element) {
rangeCheck(index); //判斷是否越界
E oldValue = elementData(index); //保存舊值用于返回
elementData[index] = element; //設(shè)置指定位置的指定值
return oldValue; //返回舊值
}
private void rangeCheck(int index) {
if (index >= size) // index >=size 就拋異常
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
get()
public E get(int index) {
rangeCheck(index); //判斷是否越界
return elementData(index); //取出指定位置的值
}
private void rangeCheck(int index) {
if (index >= size) // index >=size 就拋異常
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
remove()
public E remove(int index) {
rangeCheck(index); //判斷index 是否越界
modCount++; //修改次數(shù) + 1
E oldValue = elementData(index); //取出舊值,用于返回
int numMoved = size - index - 1;
//這個看我下面的圖
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work //用于gc回收
return oldValue; //返回舊值
}
private void rangeCheck(int index) {
if (index >= size) // index >=size 就拋異常
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
image.png
trimToSize()
public void trimToSize() {
modCount++; //修改次數(shù) + 1
if (size < elementData.length) { //元素個數(shù)是否小于于數(shù)組的容量
elementData = (size == 0) // 元素個數(shù)==0
? EMPTY_ELEMENTDATA //賦值空數(shù)組
: Arrays.copyOf(elementData, size);//否則拷貝一個元素個數(shù)長度的數(shù)組
}
}
indexOf() 記得是用對象的equals來判斷的
public int indexOf(Object o) {
if (o == null) { //因為可以存null 所以需要判斷是否是個null
for (int i = 0; i < size; i++)
if (elementData[i]==null) //是null 返回
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i])) //equals
return i;
}
return -1;
}