|
| 1 | +# java.util.ArrayList |
1 | 2 |
|
2 | | -#### java.util.ArrayList |
| 3 | +> 非特殊说明时,源码均基于AdoptOpenJDK11 |
| 4 | +> |
| 5 | +> 作者: DeleiGuo |
| 6 | +> 版权: 本文非特别声明外,均采用 © CC-BY-NC-SA 4.0 许可协议 |
3 | 7 |
|
4 | | -* 基于数组方式实现,无容量限制; |
5 | | -* 插入元素可能要扩容,删除元素并不会减少数组容量(如希望相应的缩小数组容量,可以调用ArrayList的trinToSize()),在查找元素时要遍历数组,对于非null得元素采取equals的方式寻找; |
6 | | -* ArrayList是非线程安全的; |
| 8 | +## 1. 结构 |
7 | 9 |
|
8 | | -######ArrayList:数组方式存放对象 |
9 | | -创建ArrayList(int initialCapacity) |
| 10 | +```java |
| 11 | +public class ArrayList<E> extends AbstractList<E> |
| 12 | + implements List<E>, RandomAccess, Cloneable, java.io.Serializable |
10 | 13 | ``` |
| 14 | + |
| 15 | +## 2. 属性 |
| 16 | + |
| 17 | +```java |
11 | 18 | /** |
12 | | -* Constructs an empty list with the specified initial capacity. |
13 | | -* |
14 | | -* @param initialCapacity the initial capacity of the list |
15 | | -* @throws IllegalArgumentException if the specified initial capacity |
16 | | -* is negative |
| 19 | +* Default initial capacity. |
| 20 | +* 默认容量大小为10 |
17 | 21 | */ |
18 | | -public ArrayList(int ç) { |
19 | | - super(); |
20 | | - if (initialCapacity < 0) |
21 | | - throw new IllegalArgumentException("Illegal Capacity: "+initialCapacity); |
22 | | - this.elementData = new Object[initialCapacity]; |
23 | | -} |
| 22 | +private static final int DEFAULT_CAPACITY = 10; |
| 23 | + |
| 24 | +/** |
| 25 | +* Shared empty array instance used for empty instances. |
| 26 | +* new ArrayList()无参构建函数时,大小为0 |
| 27 | +* 第一次add() 时初始化 elementData 为DEFAULT_CAPACITY |
| 28 | +*/ |
| 29 | +private static final Object[] EMPTY_ELEMENTDATA = {}; |
| 30 | + |
| 31 | +private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; |
| 32 | + |
| 33 | +/** |
| 34 | +* 存储元素的对象数组 |
| 35 | +* transient修饰 |
| 36 | +*/ |
| 37 | +transient Object[] elementData; |
| 38 | + |
| 39 | +/** |
| 40 | +* 实际存储的元素数量 |
| 41 | +*/ |
| 42 | +private int size; |
| 43 | + |
| 44 | +/** 最大的容量 */ |
| 45 | +private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; |
| 46 | + |
| 47 | +/** ===== 父类AbstractList中的重要属性 ===== */ |
| 48 | +/** 修改次数,与 fast-fail 相关 */ |
| 49 | +protected transient int modCount = 0; |
24 | 50 | ``` |
25 | | -其中,super方法调用的是AbstractList,在该类中此方法是个protected的空方法;所以,ArrayList的该方法主要是初始化了一个Object的数组,数组大小即为传入的initialCapacity。 |
26 | 51 |
|
27 | | -######插入对象:add() |
28 | | -源码: |
| 52 | +## 3. 主要方法 |
| 53 | + |
| 54 | +### 构造 |
| 55 | + |
| 56 | +``` java |
| 57 | +/** 无参构造函数 */ |
| 58 | +public ArrayList() { |
| 59 | + // 默认元素数据为空的对象数组 |
| 60 | + this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; |
| 61 | +} |
| 62 | + |
| 63 | +/** 指定初始容量的有参构造函数 */ |
| 64 | +public ArrayList(int initialCapacity) { |
| 65 | + // 判断容量参数并初始化数组 |
| 66 | + if (initialCapacity > 0) { |
| 67 | + this.elementData = new Object[initialCapacity]; |
| 68 | + } else if (initialCapacity == 0) { |
| 69 | + this.elementData = EMPTY_ELEMENTDATA; |
| 70 | + } else { |
| 71 | + throw new IllegalArgumentException("Illegal Capacity: "+ |
| 72 | + initialCapacity); |
| 73 | + } |
| 74 | +} |
29 | 75 | ``` |
| 76 | + |
| 77 | +### 操作 |
| 78 | + |
| 79 | +```java |
| 80 | +/** 添加元素 */ |
30 | 81 | public boolean add(E e) { |
31 | | - ensureCapacityInternal(size + 1); // Increments modCount!! |
32 | | - elementData[size++] = e; |
33 | | - return true; |
| 82 | + modCount++; // 此属性定义于父类AbstractList中 |
| 83 | + add(e, elementData, size); |
| 84 | + return true; |
34 | 85 | } |
35 | 86 |
|
36 | | -private void ensureCapacityInternal(int minCapacity) { |
37 | | - if (elementData == EMPTY_ELEMENTDATA) { |
38 | | - minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); |
39 | | - } |
40 | | - ensureExplicitCapacity(minCapacity); |
| 87 | +private void add(E e, Object[] elementData, int s) { |
| 88 | + if (s == elementData.length) |
| 89 | + elementData = grow(); // 扩容判断 |
| 90 | + elementData[s] = e; // 将元素放入数组相应位置 |
| 91 | + size = s + 1; // size+1 |
41 | 92 | } |
42 | 93 |
|
43 | | -private void ensureExplicitCapacity(int minCapacity) { |
44 | | - modCount++; |
45 | | -
|
46 | | - // overflow-conscious code |
47 | | - if (minCapacity - elementData.length > 0) |
48 | | - grow(minCapacity); |
| 94 | +public void add(int index, E element) { |
| 95 | + rangeCheckForAdd(index); // 数组下标越界检查 |
| 96 | + modCount++; |
| 97 | + final int s; |
| 98 | + Object[] elementData; |
| 99 | + if ((s = size) == (elementData = this.elementData).length) |
| 100 | + elementData = grow(); |
| 101 | + // 复制数组/移动 |
| 102 | + System.arraycopy(elementData, index, |
| 103 | + elementData, index + 1, |
| 104 | + s - index); |
| 105 | + elementData[index] = element; |
| 106 | + size = s + 1; |
49 | 107 | } |
50 | 108 |
|
51 | | -private void grow(int minCapacity) { |
52 | | - // overflow-conscious code |
53 | | - int oldCapacity = elementData.length; |
54 | | - int newCapacity = oldCapacity + (oldCapacity >> 1); |
55 | | - if (newCapacity - minCapacity < 0) |
56 | | - newCapacity = minCapacity; |
57 | | - if (newCapacity - MAX_ARRAY_SIZE > 0) |
58 | | - newCapacity = hugeCapacity(minCapacity); |
59 | | - // minCapacity is usually close to size, so this is a win: |
60 | | - elementData = Arrays.copyOf(elementData, newCapacity); |
| 109 | +public E remove(int index) { |
| 110 | + Objects.checkIndex(index, size); // 数组下标越界检车 |
| 111 | + final Object[] es = elementData; |
| 112 | + |
| 113 | + @SuppressWarnings("unchecked") E oldValue = (E) es[index]; |
| 114 | + fastRemove(es, index); |
| 115 | + |
| 116 | + return oldValue; |
61 | 117 | } |
62 | 118 |
|
| 119 | +private void fastRemove(Object[] es, int i) { |
| 120 | + modCount++; |
| 121 | + final int newSize; |
| 122 | + if ((newSize = size - 1) > i) |
| 123 | + // 数组复制/移动 |
| 124 | + System.arraycopy(es, i + 1, es, i, newSize - i); |
| 125 | + es[size = newSize] = null; // 将结尾的元素置为 null |
| 126 | +} |
63 | 127 | ``` |
64 | 128 |
|
65 | | -基于ArrayList中已有的元素数量+1到minCapacity,与elementData数组大小进行比较,如果大于当前elementData数组,则把当前elementData赋予给一个新的数组对象,其中通过计算当前数组值*1.5+1得出新的数组的容量,调用Arrays.copeOf方法来生成新的数组对象; |
| 129 | +### 扩容 |
66 | 130 |
|
| 131 | +```java |
67 | 132 |
|
68 | | -######删除对象:remove() |
69 | | -源码: |
70 | | -``` |
71 | | -public boolean remove(Object o) { |
72 | | - if (o == null) { |
73 | | - for (int index = 0; index < size; index++) |
74 | | - if (elementData[index] == null) { |
75 | | - fastRemove(index); |
76 | | - return true; |
77 | | - } |
78 | | - } else { |
79 | | - for (int index = 0; index < size; index++) |
80 | | - if (o.equals(elementData[index])) { |
81 | | - fastRemove(index); |
82 | | - return true; |
83 | | - } |
84 | | - } |
85 | | - return false; |
| 133 | +private Object[] grow() { |
| 134 | + return grow(size + 1); |
| 135 | +} |
| 136 | + |
| 137 | +private Object[] grow(int minCapacity) { |
| 138 | + // 适用 Arrays.copyOf 进行复制,扩容 |
| 139 | + return elementData = Arrays.copyOf(elementData, |
| 140 | + newCapacity(minCapacity)); |
86 | 141 | } |
87 | 142 |
|
88 | | -/* |
89 | | - * Private remove method that skips bounds checking and does not |
90 | | - * return the value removed. |
91 | | - */ |
92 | | -private void fastRemove(int index) { |
93 | | - modCount++; |
94 | | - int numMoved = size - index - 1; |
95 | | - if (numMoved > 0) |
96 | | - System.arraycopy(elementData, index+1, elementData, index, |
97 | | - numMoved); |
98 | | - elementData[--size] = null; // clear to let GC do its work |
| 143 | +private int newCapacity(int minCapacity) { |
| 144 | + // overflow-conscious code |
| 145 | + int oldCapacity = elementData.length; |
| 146 | + // 扩容为原来的1.5倍 |
| 147 | + int newCapacity = oldCapacity + (oldCapacity >> 1); |
| 148 | + if (newCapacity - minCapacity <= 0) { |
| 149 | + if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) |
| 150 | + return Math.max(DEFAULT_CAPACITY, minCapacity); |
| 151 | + if (minCapacity < 0) // overflow |
| 152 | + throw new OutOfMemoryError(); |
| 153 | + return minCapacity; |
| 154 | + } |
| 155 | + return (newCapacity - MAX_ARRAY_SIZE <= 0) |
| 156 | + ? newCapacity |
| 157 | + : hugeCapacity(minCapacity); |
| 158 | +} |
| 159 | + |
| 160 | +private static int hugeCapacity(int minCapacity) { |
| 161 | + if (minCapacity < 0) // overflow |
| 162 | + throw new OutOfMemoryError(); |
| 163 | + // 虽然定义了最大的容量Integer.MAX_VALUE-8,但有以下情况可以让容量达到Integer.MAX_VALUE |
| 164 | + return (minCapacity > MAX_ARRAY_SIZE) |
| 165 | + ? Integer.MAX_VALUE |
| 166 | + : MAX_ARRAY_SIZE; |
| 167 | +} |
| 168 | +``` |
| 169 | + |
| 170 | +## 4. 静态内部类SubList |
| 171 | + |
| 172 | +```java |
| 173 | +/** ArrayList 中的 subList 方法 */ |
| 174 | +public List<E> subList(int fromIndex, int toIndex) { |
| 175 | + // 调用父类AbstractList中的subListRangeCheck方法进行数组下标检查 |
| 176 | + subListRangeCheck(fromIndex, toIndex, size); |
| 177 | + // 返回的内部类 SubList,不可后续进行强转 |
| 178 | + return new SubList<>(this, fromIndex, toIndex); |
99 | 179 | } |
100 | 180 | ``` |
101 | 181 |
|
102 | | -首先判断传入对象是否为Null,如果为null,则遍历数组中已有值的元素,与传入对象进行比较是否为Null.如果为空则通过fastRemove删除相对应下标的对象,如果传入对象不为null,则通过equals方法进行比较,同样通过fastRemove方法删除; |
| 182 | +### 结构 |
| 183 | + |
| 184 | +```java |
| 185 | +/** |
| 186 | +* 该类和 ArrayList 非继承关系 |
| 187 | +*/ |
| 188 | +private static class SubList<E> extends AbstractList<E> implements RandomAccess |
| 189 | +``` |
103 | 190 |
|
104 | | -fastRemove:如果需要移动,调用底层System.arraycopy方法将index后的对象往前复制以为,并将数组的最后一个元素值设置为null,即释放了对此对象的引用 |
| 191 | +### 属性 |
105 | 192 |
|
106 | | -######判断是否包含此对象:contains |
107 | | -源码: |
| 193 | +```java |
| 194 | +private final ArrayList<E> root; // 父类,指当前的 ArrayList |
| 195 | +private final SubList<E> parent; |
| 196 | +private final int offset; |
| 197 | +private int size; |
108 | 198 | ``` |
109 | | -public boolean contains(Object o) { |
110 | | - return indexOf(o) >= 0; |
| 199 | + |
| 200 | +### 构造 |
| 201 | + |
| 202 | +```java |
| 203 | +/** SubList构造函数将原来的List和其部分属性赋值给了自己的相应属性,返回了父类的视图(View) */ |
| 204 | + |
| 205 | +public SubList(ArrayList<E> root, int fromIndex, int toIndex) { |
| 206 | + this.root = root; |
| 207 | + this.parent = null; |
| 208 | + this.offset = fromIndex; |
| 209 | + this.size = toIndex - fromIndex; |
| 210 | + this.modCount = root.modCount; |
111 | 211 | } |
112 | 212 |
|
113 | | -public int indexOf(Object o) { |
114 | | - if (o == null) { |
115 | | - for (int i = 0; i < size; i++) |
116 | | - if (elementData[i]==null) |
117 | | - return i; |
118 | | - } else { |
119 | | - for (int i = 0; i < size; i++) |
120 | | - if (o.equals(elementData[i])) |
121 | | - return i; |
122 | | - } |
123 | | - return -1; |
| 213 | +private SubList(SubList<E> parent, int fromIndex, int toIndex) { |
| 214 | + this.root = parent.root; |
| 215 | + this.parent = parent; |
| 216 | + this.offset = parent.offset + fromIndex; |
| 217 | + this.size = toIndex - fromIndex; |
| 218 | + this.modCount = parent.modCount; |
124 | 219 | } |
125 | 220 | ``` |
126 | 221 |
|
127 | | -判断是否存在该对象,需要遍历整个ArrayList的元素,如果传入对象为空,则直接判断已有元素是否为null,如果返回null,则返回true;如果传入对象不为null,则通过equals方法找寻是否有相等元素,有则返回true |
| 222 | +### 操作 |
128 | 223 |
|
129 | | -另外还有一个lastIndexOf的方法,与indexOf区别在 |
130 | | -``` |
131 | | -public int lastIndexOf(Object o) { |
132 | | - if (o == null) { |
133 | | - for (int i = size-1; i >= 0; i--) |
134 | | - if (elementData[i]==null) |
135 | | - return i; |
136 | | - } else { |
137 | | - for (int i = size-1; i >= 0; i--) |
138 | | - if (o.equals(elementData[i])) |
139 | | - return i; |
140 | | - } |
141 | | - return -1; |
| 224 | +```java |
| 225 | +/** 添加 */ |
| 226 | +public void add(int index, E element) { |
| 227 | + rangeCheckForAdd(index); // 下标检查 |
| 228 | + checkForComodification(); // fail-fast 检查 |
| 229 | + root.add(offset + index, element); // 调用的是 ArrayList 的 add 方法 |
| 230 | + updateSizeAndModCount(1); |
142 | 231 | } |
143 | 232 | ``` |
| 233 | + |
| 234 | +SubList单独定义了set、get、size、add、remove等操作方法,操作了ArrayList的同一个elementData数组,即对SubList进行修改时,也会影响到ArrayList的数据。 |
| 235 | + |
0 commit comments