/** * public方法,让用户能手动设置ArrayList的容量 * @param minCapacity 期望的最小容量 */ publicvoidensureCapacity(int minCapacity){ int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) // any size if not default element table ? 0 // larger than default for default empty table. It's already // supposed to be at default size. : DEFAULT_CAPACITY;
if (minCapacity > minExpand) { ensureExplicitCapacity(minCapacity); } }
/** * 移除此列表中指定位置上的元素 * @param index 需被移除的元素的索引 * @return the element 被移除的元素值 * @throws IndexOutOfBoundsException {@inheritDoc} */ public E remove(int index) { rangeCheck(index); //判断index是否 <= size
modCount++; E oldValue = elementData(index); //将数组elementData中index位置之后的所有元素向前移一位 int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; //将原数组最后一个位置置为null,由GC清理
return oldValue; }
//移除ArrayList中首次出现的指定元素(如果存在),ArrayList中允许存放重复的元素 publicboolean remove(Object o) { // 由于ArrayList中允许存放null,因此下面通过两种情况来分别处理。 if (o == null) { for (int index = 0; index < size; index++) if (elementData[index] == null) { fastRemove(index); //私有的移除方法,跳过index参数的边界检查以及不返回任何值 returntrue; } } else { for (int index = 0; index < size; index++) if (o.equals(elementData[index])) { fastRemove(index); returntrue; } } returnfalse; }
//私有的删除指定位置元素的方法,跳过index参数的边界检查以及不返回任何值 privatevoid fastRemove(int index) { modCount++; int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // clear to let GC do its work }
// clear to let GC do its work for (int i = 0; i < size; i++) elementData[i] = null;
size = 0; }
//删除ArrayList中从fromIndex(包含)到toIndex(不包含)之间所有的元素,共移除了toIndex-fromIndex个元素 protectedvoid removeRange(int fromIndex, int toIndex) { modCount++; int numMoved = size - toIndex; //需向前移动的元素的个数 System.arraycopy(elementData, toIndex, elementData, fromIndex, numMoved);
// clear to let GC do its work int newSize = size - (toIndex-fromIndex); for (int i = newSize; i < size; i++) { elementData[i] = null; } size = newSize; }
//判断ArrayList中是否包含Object(o) public boolean contains(Object o){ return indexOf(o) >= 0; }
//正向查找,返回ArrayList中元素Object o第一次出现的位置,如果元素不存在,则返回-1 publicintindexOf(Object o){ if (o == null) { for (int i = 0; i < size; i++) if (elementData[i]==null) return i; } else { for (int i = 0; i < size; i++) if (o.equals(elementData[i])) return i; } return -1; }
//逆向查找,返回ArrayList中元素Object o最后一次出现的位置,如果元素不存在,则返回-1 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; }
@SuppressWarnings("unchecked") E elementData(int index){ return (E) elementData[index]; }
//返回指定索引处的值 public E get(int index){ rangeCheck(index);
//返回此 ArrayList实例的浅拷贝 publicObject 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中所有元素的数组 publicObject[] toArray() { return Arrays.copyOf(elementData, size); }
//如果给定的参数数组长度足够,则将ArrayList中所有元素按序存放于参数数组中,并返回 //如果给定的参数数组长度小于ArrayList的长度,则返回一个新分配的、长度等于ArrayList长度的、包含ArrayList中所有元素的新数组 @SuppressWarnings("unchecked") public <T> T[] toArray(T[] a) { if (a.length < size) // Make a new array of a's runtime type, but my contents: return (T[]) Arrays.copyOf(elementData, size, a.getClass()); System.arraycopy(elementData, 0, a, 0, size); if (a.length > size) a[size] = null; return a; }
/序列化:将ArrayList的“大小,所有的元素值”都写入到输出流中 private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException{ // Writeout element count, and any hidden stuff int expectedModCount = modCount; s.defaultWriteObject();
// Writeoutsize as capacity for behavioural compatibility with clone() s.writeInt(size);
// Writeoutall elements in the proper order. for (int i=0; i<size; i++) { s.writeObject(elementData[i]); }
if (modCount != expectedModCount) { throw new ConcurrentModificationException(); } }