前言:最近对Java的集合结合源码重新看了一遍,如有错误请立即指正
ArraryList
- 初始化
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
private static final Object[] EMPTY_ELEMENTDATA = {};
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
如果初始化为无参数ArrayList,容量为0。初始化为有参ArrayList且参数为0,初始化为空,小于零抛出异常
- 扩容
private static final int DEFAULT_CAPACITY = 10;
public boolean add(E e) {
modCount++;
add(e, elementData, size);
return true;
}
private void add(E e, Object[] elementData, int s) {
//s=size,判断list长度是否与容量大小相等,如果相等则需要扩容
if (s == elementData.length)
elementData = grow();
//如果不需要扩容则直接对list进行赋值
elementData[s] = e;
size = s + 1;
}
public void add(int index, E element) {
//检测是否越界
rangeCheckForAdd(index);
modCount++;
final int s;
Object[] elementData;
//如果size刚好等于arraylist的容量大小,扩容
if ((s = size) == (elementData = this.elementData).length)
elementData = grow();
System.arraycopy(elementData, index,
elementData, index + 1,
s - index);
elementData[index] = element;
size = s + 1;
}
private Object[] grow() {
//如果进行无参扩容,默认参数为size+1,size+1为扩容最小容量
return grow(size + 1);
}
private Object[] grow(int minCapacity) {
//复制
return elementData = Arrays.copyOf(elementData,
newCapacity(minCapacity));
}
private int newCapacity(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
//扩容按照原容量1.5倍进行
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity <= 0) {
//用于无参构造方法的初始化默认为10的容量
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
return Math.max(DEFAULT_CAPACITY, minCapacity);
//minCapacity超出int最大限度,溢出,抛出异常
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return minCapacity;
}
//如果newCapacity大于MAX_ARRAY_size,则扩容为Integer.MAX_VAlUE
return (newCapacity - MAX_ARRAY_SIZE <= 0)
? newCapacity
: hugeCapacity(minCapacity);
}
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE)
? Integer.MAX_VALUE
: MAX_ARRAY_SIZE;
}
在调用add方法时,需要对list的容器大小进行一个判断
,如果size大小正好等于容器长度,则需要一次扩容才能进行增加元素的操作,即扩容。由于无参构造方法时,初始化容量为0,此时调用add方法时,需要扩容,且此时扩容直接给到10的容量大小。扩容时,新的容器大小是原容器的1.5倍,此时考虑到扩容之后可能出现新容器大小大于int的最大长度而溢出的情况
- toArray()方法
//无参构造返回object()对象
public Object[] toArray() {
return Arrays.copyOf(elementData, size);
}
//有参构造中,先对a的长度进行判断,如果长度小于list长度,则调用Arrays.copyof方法进行复制,直接返回,此时并没有对传入数组a进行复制操作而是将复制好的数组返回
public <T> T[] toArray(T[] a) {
if (a.length < size)
// Make a new array of a's runtime type, but my contents:
return (T[]) Arrays.copyOf(elementData, size, a.getClass());
//容量足够时直接进行复制到数组a中
System.arraycopy(elementData, 0, a, 0, size);
if (a.length > size)
a[size] = null;
return a;
}
public static <T> T[] copyOf(T[] original, int newLength) {
return (T[]) copyOf(original, newLength, original.getClass());
}
public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
//在方法内部创建一个数组,然后进行复制,返回复制好的数组
@SuppressWarnings("unchecked")
T[] copy = ((Object)newType == (Object)Object[].class)
? (T[]) new Object[newLength]
: (T[]) Array.newInstance(newType.getComponentType(), newLength);
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
该方法主要包括三点:1.当进行无参构造时,反省丢失,返回类型为object。2.数组长度小于list长度,调用Arrays.copyof方法,方法内部重新创建一个数组,对该数组进行复制,返回该数组,没有对传入数组进行操作。3.容量足够时直接将list中的内容复制进a中
- clone()浅拷贝
public Object clone() {
try {
//继承了object的clone方法进行浅拷贝
ArrayList<?> v = (ArrayList<?>) super.clone();
v.elementData = Arrays.copyOf(elementData, size);
v.modCount = 0;
return v;
} catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable
throw new InternalError(e);
}
}
浅拷贝:两个变量指示内存中的地址是不一样的,但是变量中的元素指向同一个元素。