ArrayList源碼閱讀
屬性字段
private static final long serialVersionUID = 8683452581122892189L;
//默認(rèn)大小
private static final int DEFAULT_CAPACITY = 10;
//空數(shù)組
private static final Object[] EMPTY_ELEMENTDATA = {};
//從EMPTY_ELEMENTDATA獨(dú)立出來(lái)丛晦,專門用于無(wú)參構(gòu)造函數(shù)時(shí)的指向瓣蛀,起標(biāo)識(shí)作用
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
//默認(rèn)數(shù)組
transient Object[] elementData; // non-private to simplify nested class access
private int size;
構(gòu)造方法
1)無(wú)參構(gòu)造函數(shù)
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
2) 參數(shù)為容器大小的構(gòu)造函數(shù)
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
//創(chuàng)建數(shù)組
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
//指向空數(shù)組
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
3)參數(shù)為其他list的構(gòu)造函數(shù)
public ArrayList(Collection<? extends E> c) {
//指向新數(shù)組
elementData = c.toArray();
if ((size = elementData.length) != 0) {
// c.toArray 可能返回的不是Object類型的數(shù)組所以加上下面的語(yǔ)句用于判斷,
//這里用到了反射里面的getClass()方法
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else {
// replace with empty array.
this.elementData = EMPTY_ELEMENTDATA;
}
}
add添加
直接再末位添加元素
public boolean add(E e) {
//判斷是否要擴(kuò)容磺送,并自增modCount
ensureCapacityInternal(size + 1); // Increments modCount!!
//添加元素
elementData[size++] = e;
return true;
}
指定位置添加元素
public void add(int index, E element) {
//驗(yàn)證下標(biāo)是否在指定范圍
rangeCheckForAdd(index);
//判斷是否要擴(kuò)容留夜,并自增modCount
ensureCapacityInternal(size + 1); // Increments modCount!!
//復(fù)制數(shù)組真椿,騰出空位
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
//添加元素
elementData[index] = element;
//大小加1
size++;
}
添加一個(gè)集合
public boolean addAll(Collection<? extends E> c) {
Object[] a = c.toArray();
int numNew = a.length;
//判斷是否要擴(kuò)容娜遵,并自增modCount
ensureCapacityInternal(size + numNew); // Increments modCount
//復(fù)制
System.arraycopy(a, 0, elementData, size, numNew);
//大小改變
size += numNew;
return numNew != 0;
}
擴(kuò)容方法
ensureCapacityInternal()
實(shí)現(xiàn)對(duì)grow的封裝
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
calculateCapacity()
第一次添加元素時(shí)丽声,判斷時(shí)擴(kuò)容為默認(rèn)大小礁蔗,還是擴(kuò)容為minCapacity.總感覺(jué)這是一個(gè)無(wú)用的方法
private static int calculateCapacity(Object[] elementData, int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
ensureExplicitCapacity()
改變modCount,并判斷是否需要擴(kuò)容雁社,
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
grow()
真正的擴(kuò)容方法
private void grow(int minCapacity) {
// overflow-conscious code
//原來(lái)的大小
int oldCapacity = elementData.length;
//擴(kuò)容為原來(lái)的1.5倍
int newCapacity = oldCapacity + (oldCapacity >> 1);
//在擴(kuò)容為原來(lái)的1.5倍還不滿足條件的時(shí)候
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// 復(fù)制為一個(gè)新的數(shù)組
elementData = Arrays.copyOf(elementData, newCapacity);
}
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
//MAX_ARRAY_SIZE=8
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
remove刪除
刪除指定下標(biāo)的元素
public E remove(int index) {
//判斷范圍
rangeCheck(index);
//自增modCount
modCount++;
//獲得要?jiǎng)h除的值
E oldValue = elementData(index);
int numMoved = size - index - 1;
if (numMoved > 0)
//把后面的值全部向前挪一位
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
//最后以為置空浴井,并減小數(shù)組大小size, 置空有利于GC回收
elementData[--size] = null; // clear to let GC do its work
return oldValue;
}
刪除指定元素
public boolean remove(Object o) {
//如果要?jiǎng)h除的元素是null,
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {//刪除正常的值
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
}
//和刪除指定下標(biāo)元素的方法一樣霉撵。
private void fastRemove(int index) {
modCount++;
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
}
get方法
很簡(jiǎn)單的邏輯
public E get(int index) {
//判斷范圍
rangeCheck(index);
//返回對(duì)應(yīng)值
return elementData(index);
}
set方法
public E set(int index, E element) {
//判斷范圍
rangeCheck(index);
//獲得舊元素
E oldValue = elementData(index);
//更新
elementData[index] = element;
//返回
return oldValue;
}