//这个方法首先定义数组新的长度为原来数组长度的1.5倍,如果新长度减去所需数组的最小长度小于0,那么新长度就等于所需数组最小长度;再下面的判断是如果新长度大于MAX_ARRAY_SIZE(ArrayList内部定义MAX_ARRAY_SIZE的值是:2147483639)就调用hugeCapacity方法,最后调用Arrays.copyOf将扩容后的新数组地址赋值给elementData privatevoidgrow(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); }
public E remove(int index){ //判断删除位置是否正确,如果大于列表长度会抛出异常 rangeCheck(index); //将集合修改次数加1 modCount++; //获取当前删除位置上的元素 E oldValue = elementData(index); //判断是否删除的是最后一个元素,如果不是将删除位置后的元素向左移numMoved个位置 int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); //将列表最后的元素置为null,等待垃圾收集器收集 elementData[--size] = null; // clear to let GC do its work //返回删除位置老的值 return oldValue; }
1
remove(Object o) //移除指定元素
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
publicbooleanremove(Object o){ //因为ArrayList允许存在null,所以需要进行null判断 if (o == null) { for (int index = 0; index < size; index++) if (elementData[index] == null) { //移除这个位置的元素 fastRemove(index); returntrue; } } else { for (int index = 0; index < size; index++) if (o.equals(elementData[index])) { fastRemove(index); returntrue; } } returnfalse; }
1 2 3 4 5 6 7 8 9 10 11
privatevoidfastRemove(int index){ //将集合修改次数加1 modCount++; //判断是否删除的是最后一个元素,如果不是将删除位置后的元素向左移numMoved个位置 int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); //将列表最后的元素置为null,等待垃圾收集器收集 elementData[--size] = null; // clear to let GC do its work }
privatebooleanbatchRemove(Collection<?> c, boolean complement){ final Object[] elementData = this.elementData; int r = 0, w = 0; boolean modified = false; try { //遍历数组,并检查这个集合是否包含对应的值,移动要保留的值到数组前面,w最后值为要保留的元素的数量 //若保留,就将相同的元素移动到前段;不删除,就将不同元素移动到前段 for (; r < size; r++) if (c.contains(elementData[r]) == complement) elementData[w++] = elementData[r]; } finally { // 确保异常抛出前的部分可以完成期望的操作,而被遍历的部分会被接到后面 //r不等于size表示可能出错了 if (r != size) { System.arraycopy(elementData, r, elementData, w, size - r); w += size - r; } //如果w等于size,表示全部元素都保留了,所以也就没有删除操作发生,所以会返回false;反之,返回true,并更改数组 //而w不等于size的时候,即使try块抛出异常,也能正确处理异常抛出前的操作,因为w始终为要保留的前段部分的长度,数组也不会因此乱序 if (w != size) { // clear to let GC do its work for (int i = w; i < size; i++) elementData[i] = null; modCount += size - w; size = w; modified = true; } } return modified; }
1
clear() //清空ArrayList内的所有元素,不减小数组容量
1 2 3 4 5 6 7 8 9 10
publicvoidclear(){ //将集合修改次数加1 modCount++; //循环将列表中的所有元素置为null,等待垃圾收集器收集 // clear to let GC do its work for (int i = 0; i < size; i++) elementData[i] = null; //将列表长度设为0 size = 0; }
publicintindexOf(Object o){ //因为ArrayList允许存在null,所以需要进行null判断 if (o == null) { //遍历列表,如果列表存在null值的元素,直接返回其下标位置 for (int i = 0; i < size; i++) if (elementData[i]==null) return i; } else { //遍历列表,使用equals判断是否有相等的元素,有的话直接返回其下标位置 for (int i = 0; i < size; i++) if (o.equals(elementData[i])) return i; } //列表中不能存在传进来的元素,返回-1 return -1; }
//反向查找元素位置,与上述的indexOf相反 publicintlastIndexOf(Object o){ if (o == null) { for (int i = size-1; i >= 0; i--) if (elementData[i]==null) return i; } else { for (int i = size-1; i >= 0; i--) if (o.equals(elementData[i])) return i; } return -1; }
//将元素全部拷贝到v中 public Object clone(){ try { 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 thrownew InternalError(e); } }
//返回ArrayList拷贝后的Object数组 public Object[] toArray() { return Arrays.copyOf(elementData, size); }
//返回ArrayList的模板数组。所谓模板数组,即可将T设置为任意数据类型 public <T> T[] toArray(T[] a) { //若a的长度小于ArrayList中的元素个数,返回拷贝了ArrayList中全部元素的新数组 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的长度大于等于ArrayList中的元素个数,则将ArrayList中的元素全部拷贝到a中 System.arraycopy(elementData, 0, a, 0, size); if (a.length > size) a[size] = null; return a; }
//将ArrayList中的元素写入到输入流中,先写容量,在写元素 privatevoidwriteObject(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) { thrownew ConcurrentModificationException(); } }
// Read in size, and any hidden stuff s.defaultReadObject();
// Read in capacity s.readInt(); // ignored
if (size > 0) { // be like clone(), allocate array based upon size not capacity int capacity = calculateCapacity(elementData, size); SharedSecrets.getJavaOISAccess().checkArray(s, Object[].class, capacity); ensureCapacityInternal(size);
Object[] a = elementData; // Read in all elements in the proper order. for (int i=0; i<size; i++) { a[i] = s.readObject(); } } }