1 /*
2 继承自AbstractList,实现了List、RandomAccess、Cloneable、Serializable接口3 1)RandomAccess接口:用来快速随机存取,在实现了该接口后,用普通for来遍历,性能更高4 2)Cloneable接口:实现了该接口,就可以使用Object.Clone()方法了5 3)Serializable接口:实现了该接口,表明该类可以被序列化6 */
7 public class ArrayList extends AbstractList
8 implements List, RandomAccess, Cloneable, java.io.Serializable9 {10 //版本号
11 private static final long serialVersionUID = 8683452581122892189L;12 //缺省容量
13 private static final int DEFAULT_CAPACITY = 10;14 //缺省空对象数组
15 private static final Object[] EMPTY_ELEMENTDATA ={};16 //默认大小的对象数组
17 private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA ={};18 //元素数组
19 transientObject[] elementData;20 //数组的大小
21 private intsize;22
23 //构造方法24 //无参构造 Constructs an empty list with an initial capacity of ten
25 publicArrayList() {26 this.elementData =DEFAULTCAPACITY_EMPTY_ELEMENTDATA;27 }28
29 /**
30 * Constructs an empty list with the specified initial capacity.31 *32 *@paraminitialCapacity the initial capacity of the list33 *@throwsIllegalArgumentException if the specified initial capacity34 * is negative35 */
36 public ArrayList(intinitialCapacity) {37 if (initialCapacity > 0) {38 this.elementData = newObject[initialCapacity];39 } else if (initialCapacity == 0) {40 this.elementData =EMPTY_ELEMENTDATA;41 } else{42 throw new IllegalArgumentException("Illegal Capacity: "+
43 initialCapacity);44 }45 }46
47 /**
48 * Constructs a list containing the elements of the specified49 * collection, in the order they are returned by the collection's50 * iterator.51 *52 *@paramc the collection whose elements are to be placed into this list53 *@throwsNullPointerException if the specified collection is null54 */
55 public ArrayList(Collection extends E>c) {56 elementData = c.toArray(); //转换为数组
57 if ((size = elementData.length) != 0) { //数组长度大于058 //c.toArray might (incorrectly) not return Object[] (see 6260652)
59 if (elementData.getClass() != Object[].class)60 elementData = Arrays.copyOf(elementData, size, Object[].class);61 } else{62 //replace with empty array.
63 this.elementData =EMPTY_ELEMENTDATA;64 }65 }66 //总体而言:arrayList的构造方法就是做一件事,初始化一下储存数据的容器,67 //其实本质就是一个数组,在其中就叫elementData68
69 //核心方法
70 /**
71 * Appends the specified element to the end of this list.72 * 默认直接在末尾添加元素73 *74 *@parame element to be appended to this list75 *@returntrue (as specified by {@linkCollection#add})76 */
77 public boolean add(E e) { //elementData=[1,2,3] e=678 //确保数组的容量足够
79 ensureCapacityInternal(size + 1); //Increments modCount!!80 //数组尾部添加元素e
81 elementData[size++] =e;82 return true;83 }84
85 private void ensureCapacityInternal(int minCapacity) { //minCapacity=4
87 ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));88 }89
90 //计算容量
91 private static int calculateCapacity(Object[] elementData, int minCapacity) {//elementData=[1,2,3],minCapacity=492 //如果元素数组等于默认容量的元素数组,就返回DEFAULT_CAPACITY和minCapacity两者的最大值
93 if (elementData ==DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {94 returnMath.max(DEFAULT_CAPACITY, minCapacity);95 }96 //否则就返回minCapacity
97 return minCapacity; //4
98 }99
100 private void ensureExplicitCapacity(int minCapacity) { //minCapacity=4
101 modCount++;102
103 //overflow-conscious code
104 /*
105 这里有两种情况:106 情况一:elementData为空数组,minCapacity=size+1=1,1-0>0,调用grow()进行扩容107 情况二:elementData不为空数组,minCapacity=size+1,为elementData原始的数组(未调用add方法前),108 如果length不够用,再调用grow()进行扩容109 */
110 if (minCapacity - elementData.length > 0)111 grow(minCapacity);112 }113
114 /**
115 * 增加容量以确保它至少可以容纳由最小容量参数指定的元素数116 * Increases the capacity to ensure that it can hold at least the117 * number of elements specified by the minimum capacity argument.118 *119 *@paramminCapacity the desired minimum capacity120 */
121 private void grow(intminCapacity) {122 //overflow-conscious code123 //将原始的elementData.length赋给oldCapacity
124 int oldCapacity =elementData.length;125 //新容量=1.5*oldCapacity
126 int newCapacity = oldCapacity + (oldCapacity >> 1);127 //如果elementData为空数组,那么oldCapacity和newCapacity都为0,将newCapacity直接赋值为10
128 if (newCapacity - minCapacity < 0)129 newCapacity =minCapacity;130 //如果newCapacity超过了最大的容量限制,将调用hugeCapacity()做进一步处理
131 if (newCapacity - MAX_ARRAY_SIZE > 0)132 newCapacity =hugeCapacity(minCapacity);133 //minCapacity is usually close to size, so this is a win:134 //newCapacity确定好了以后,就copyof数组,进行扩容
135 elementData =Arrays.copyOf(elementData, newCapacity);136 }137
138 private static int hugeCapacity(intminCapacity) {139 if (minCapacity < 0) //overflow
140 throw newOutOfMemoryError();141 //判断minCapacity是否大于最大的数组容量MAX_ARRAY_SIZE:是,返回Integer.MAX_VALUE(2147483647);142 //否则返回MAX_ARRAY_SIZE
143 return (minCapacity > MAX_ARRAY_SIZE) ?
144 Integer.MAX_VALUE :145 MAX_ARRAY_SIZE;146 }147
148 /**
149 * 在指定位置插入元素150 * Inserts the specified element at the specified position in this151 * list. Shifts the element currently at that position (if any) and152 * any subsequent elements to the right (adds one to their indices).153 *154 *@paramindex index at which the specified element is to be inserted155 *@paramelement element to be inserted156 *@throwsIndexOutOfBoundsException {@inheritDoc}157 */
158 public void add(intindex, E element) {159 //检查插入的位置是否合理
160 rangeCheckForAdd(index);161
162 //插入元素之后,将index之后的元素都往后移一位
163 ensureCapacityInternal(size + 1); //Increments modCount!!
164 System.arraycopy(elementData, index, elementData, index + 1,165 size -index);166 elementData[index] =element;167 size++;168 }169
170 /**
171 * 用于add和addAll方法的范围检查172 * A version of rangeCheck used by add and addAll.173 */
174 private void rangeCheckForAdd(intindex) {175 if (index > size || index < 0)176 throw newIndexOutOfBoundsException(outOfBoundsMsg(index));177 }178
179 /**
180 * 删除指定位置的元素181 * Removes the element at the specified position in this list.182 * Shifts any subsequent elements to the left (subtracts one from their183 * indices).184 *185 *@paramindex the index of the element to be removed186 *@returnthe element that was removed from the list187 *@throwsIndexOutOfBoundsException {@inheritDoc}188 */
189 public E remove(intindex) {190 //范围检查
191 rangeCheck(index);192
193 modCount++;194 E oldValue = elementData(index); //要删除指定index位置的值195
196 //计算要移动的位数
197 int numMoved = size - index - 1;198 if (numMoved > 0)199 /*
200 public static native void arraycopy(Object src, int srcPos,201 Object dest, int destPos,202 int length);203 Copies an array from the specified source array, beginning at the204 specified position, to the specified position of the destination array.205 从源数组的特殊位置开始拷贝到目标数组的特定位置206
207 System.arraycopy(elementData, index+1, elementData, index,208 size - index - 1); //size=8,index=5,8-5-1=2,src=[1,2,3,4,5,7,8]209 */
210 System.arraycopy(elementData, index+1, elementData, index,211 numMoved);212 elementData[--size] = null; //clear to let GC do its work
213
214 returnoldValue;215 }216
217 /**
218 * 移除list列表中第一次出现的待删除的元素219 * Removes the first occurrence of the specified element from this list,220 * if it is present. If the list does not contain the element, it is221 * unchanged. More formally, removes the element with the lowest index222 * i such that223 * (o==null ? get(i)==null : o.equals(get(i)))224 * (if such an element exists). Returns true if this list225 * contained the specified element (or equivalently, if this list226 * changed as a result of the call).227 *228 *@paramo element to be removed from this list, if present229 *@returntrue if this list contained the specified element230 */
231 public booleanremove(Object o) {232 //依次遍历删除
233 if (o == null) {234 for (int index = 0; index < size; index++)235 if (elementData[index] == null) {236 fastRemove(index);237 return true;238 }239 } else{240 for (int index = 0; index < size; index++)241 if(o.equals(elementData[index])) {242 fastRemove(index);243 return true;244 }245 }246 return false;247 }248 //remove函数用户移除指定下标的元素,此时会把指定下标到数组末尾的元素向前移动一个单位,249 //并把最后一个元素置为null
250
251 /**
252 * 将list表中指定位置的元素替换掉253 * Replaces the element at the specified position in this list with254 * the specified element.255 *256 *@paramindex index of the element to replace257 *@paramelement element to be stored at the specified position258 *@returnthe element previously at the specified position259 *@throwsIndexOutOfBoundsException {@inheritDoc}260 */
261 public E set(intindex, E element) {262 //范围检查
263 rangeCheck(index);264
265 //指定位置的元素值
266 E oldValue =elementData(index);267 //将elementData的指定位置替换为element
268 elementData[index] =element;269 returnoldValue;270 }271
272 /**
273 * 返回在list列表中的指定元素第一次出现的索引值274 * Returns the index of the first occurrence of the specified element275 * in this list, or -1 if this list does not contain the element.276 * More formally, returns the lowest index i such that277 * (o==null ? get(i)==null : o.equals(get(i))),278 * or -1 if there is no such index.279 */
280 public intindexOf(Object o) {281 if (o == null) {282 for (int i = 0; i < size; i++)283 if (elementData[i]==null)284 returni;285 } else{286 for (int i = 0; i < size; i++)287 if(o.equals(elementData[i]))288 returni;289 }290 return -1;291 }292 //从头开始查找元素,可以查找null值
293
294 /**
295 * 返回在list列表中指定位置的元素296 * Returns the element at the specified position in this list.297 *298 *@paramindex index of the element to return299 *@returnthe element at the specified position in this list300 *@throwsIndexOutOfBoundsException {@inheritDoc}301 */
302 public E get(intindex) {303 //范围检查,只检查>=size的部分
304 rangeCheck(index);305
306 returnelementData(index);307 }308
309 E elementData(intindex) {310 return(E) elementData[index];311 }312 //注意:返回的值都做了向下转型(object->E)处理
313 }