Java集合类-ArrayList分析
ArrayList的特点
非线程安全
支持序列化
可以动态扩容
线程安全的List Collections.synchronizedList、CopyOnWriteArrayList
成员变量
private static final int DEFAULT_CAPACITY = 10; // 初始大小
transient Object[] elementData; // 存储元素的数组
private int size; //容器大小
基本方法
增 add
public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; }
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
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)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
删 remove
public E remove(int index) { rangeCheck(index); modCount++; E oldValue = elementData(index); int numMoved = size - index - 1;
// 向前移动numMoved个元素,最后一个元素置为null if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // clear to let GC do its work return oldValue; } private void rangeCheck(int index) { if (index >= size) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); }
改 set
public E set(int index, E element) { rangeCheck(index); E oldValue = elementData(index); elementData[index] = element; return oldValue; }
查 get
public E get(int index) { rangeCheck(index); return elementData(index); }
ArrayList扩容原理
如果新加入元素后数组容量不够需要进行扩容,执行grow方法
默认扩容为之前的1.5倍,如果容量不够则直接扩充为加入当新元素后的大小
然后利用Arrays.copyOf进行数组的复制
相关类和方法
Arrays.copyOf()
System.arraycopy()
public static native void arraycopy(
Object src,
int srcPos,
Object dest,
int destPos,
int length
);
一些问题
ArrayList如何序列化?
private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException{ // Write out element count, and any hidden stuff int expectedModCount = modCount; s.defaultWriteObject(); // Write out size as capacity for behavioural compatibility with clone() s.writeInt(size); // Write out all elements in the proper order. for (int i=0; i<size; i++) { s.writeObject(elementData[i]); } if (modCount != expectedModCount) { throw new ConcurrentModificationException(); } }
序列化时JVM调用writeObject方法,只将数组size内的元素进行序列化,多余空间不进行序列化
参考
http://blog.csdn.net/ns_code/article/details/35568011
http://blog.csdn.net/qfycc92/article/details/45370011