变量
elementData 是用 transient 修饰的
ArrayList 实现了 Serializable 接口,这意味着 ArrayList 是可以被序列化的,用 transient 修饰 elementData 意味着不希望 elementData 数组被序列化
因为序列化 ArrayList 的时候,elementData 未必是满的
- 比方说 elementData 有 10 的大小,但是只用了其中的 3 个,那么没有必要序列化整个 elementData ,因此 ArrayList 中重写了 writeObject 方法
- 提高了序列化的效率,减少了无意义的序列化
- 减少了序列化后文件大小
初始化 & 扩容
ArrayList 的初始化是在插入的时候,跟 HashMap 一样
扩容也在插入的时候判断
- 扩容后的数组大小是
newCapacity = oldCapacity + (oldCapacity >> 1)
- 初始化发生在
calculateCapacity
里面( 这里是针对没指定数组大小的初始化,如果给了指定的数组大小,初始化就在构造里 )
- 扩容在 grow 方法里面
对于没有指定数组大小的构造,直接给一个空数组
1 2 3 4
| private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; }
|
对于有指定大小的,直接在构造里初始化
1 2 3 4 5 6 7 8 9
| public ArrayList(int initialCapacity) { if (initialCapacity > 0) { this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) { this.elementData = EMPTY_ELEMENTDATA; } else { } }
|
精华都在注释里
( 下面的 初始化 是针对没指定数组大小的情况!!! )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
| public boolean add(E e) { ensureCapacityInternal(size + 1);
elementData[size++] = e; return true; }
private void ensureCapacityInternal(int minCapacity) { ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); }
private static int calculateCapacity(Object[] elementData, int minCapacity) { if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { return Math.max(DEFAULT_CAPACITY, minCapacity); } return minCapacity; }
private void ensureExplicitCapacity(int minCapacity) { modCount++;
if (minCapacity - elementData.length > 0) grow(minCapacity);
}
private void grow(int minCapacity) { int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity); }
private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) throw new OutOfMemoryError(); return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; }
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) {
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; }
|
遍历
迭代器最强
对于集合的迭代器,请看 集合的迭代器
子集
SubList 是 ArrayList 的子类
其实也就那样,大多数用的还是 ArrayList 的接口
1 2 3 4
| public List<E> subList(int fromIndex, int toIndex) { subListRangeCheck(fromIndex, toIndex, size); return new SubList(this, 0, fromIndex, toIndex); }
|