package java.util; public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable { private static final long serialVersionUID = 8683452581122892189L; /** * 数据存储数组 */ private transient Object[] elementData; /** * 存储数据的个数 */ private int size; /** * 根据容量参数初始化 */ public ArrayList(int initialCapacity) { super(); //小于0,抛参数异常 if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); //新建一个数组 this.elementData = new Object[initialCapacity]; } /** * 无参构造方法(默认容量为10) */ public ArrayList() { this(10); } /** * 根据参数构造一个包含指定集合的List */ public ArrayList(Collection<? extends E> c) { elementData = c.toArray(); size = elementData.length; // c.toArray might (incorrectly) not return Object[] (see 6260652) if (elementData.getClass() != Object[].class) elementData = Arrays.copyOf(elementData, size, Object[].class); } /** * 将当前容量值设为实际元素个数 */ public void trimToSize() { modCount++; //容量 int oldCapacity = elementData.length; //实际存储小于容量,数组复制 if (size < oldCapacity) { elementData = Arrays.copyOf(elementData, size); } } /** * 扩展容量 * 若ArrayList的容量不足以容纳当前的全部元素,设置 新的容量=“(原始容量x3)/2 + 1” */ public void ensureCapacity(int minCapacity) { modCount++; //容量 int oldCapacity = elementData.length; //最小容量大于当前容量 if (minCapacity > oldCapacity) { Object oldData[] = elementData; //新容量,每次扩容1.5倍(加1,向上取整,防止elementData[size]时越界) int newCapacity = (oldCapacity * 3)/2 + 1; //新容量和最小容量相比较,取较大值 if (newCapacity < minCapacity) newCapacity = minCapacity; // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); } } /** * 返回ArrayList的实际大小 */ public int size() { return size; } /** * ArrayList是否为空 */ public boolean isEmpty() { return size == 0; } /** * 返回ArrayList是否包含Object(o) */ public boolean contains(Object o) { return indexOf(o) >= 0; } /** * 正向查找,返回ArrayList中指定元素的第一个匹配项的索引 */ public int indexOf(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; } //不存在 -1 return -1; } /** * * 反向查找,返回指定元素最后一次出现的索引 * */ public int lastIndexOf(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; } /** * 浅克隆(只克隆引用,数据本身不克隆) * */ public Object clone() { try { //克隆一个实例 ArrayList<E> v = (ArrayList<E>) super.clone(); //将当前ArrayList的全部元素拷贝到v中 v.elementData = Arrays.copyOf(elementData, size); //初始化列表更新次数 v.modCount = 0; //返回实例 return v; } catch (CloneNotSupportedException e) { // this shouldn't happen, since we are Cloneable throw new InternalError(); } } /** * 返回ArrayList的Object数组 * */ public Object[] toArray() { return Arrays.copyOf(elementData, size); } /** * 返回ArrayList的泛型数组。所谓泛型数组,即可以将T设为任意的数据类型 */ public <T> T[] toArray(T[] a) { // 如果传入数组的长度小于size,返回一个新的数组, // 大小为size,类型与传入数组相同。 if (a.length < size) return (T[]) Arrays.copyOf(elementData, size, a.getClass()); // 所传入数组长度与size相等,则将elementData复制到传入数组中并返 // 回传入的数组。 System.arraycopy(elementData, 0, a, 0, size); // 若传入数组长度大于size,除了复制 // elementData外,还将把返回数组的第size个元素置为空。 if (a.length > size) a[size] = null; return a; } // Positional Access Operations /** * 获取index位置的元素值 */ public E get(int index) { RangeCheck(index); return (E) elementData[index]; } /** * 设置index位置的值为element */ public E set(int index, E element) { RangeCheck(index); E oldValue = (E) elementData[index]; elementData[index] = element; return oldValue; } /** * 将e添加到ArrayList中 */ public boolean add(E e) { //根据存储数据设置最小容量(判断是否需要扩容) ensureCapacity(size + 1); // Increments modCount!! //插入数据 elementData[size++] = e; return true; } /** * 将e添加到ArrayList的指定位置 */ public void add(int index, E element) { //判断数组是否越界 if (index > size || index < 0) throw new IndexOutOfBoundsException( "Index: "+index+", Size: "+size); //根据存储数据设置最小容量(判断是否需要扩容) ensureCapacity(size+1); // Increments modCount!! System.arraycopy(elementData, index, elementData, index + 1,size - index); elementData[index] = element; size++; } /** * 删除ArrayList指定位置的元素 */ public E remove(int index) { // 检查索引是否越界 RangeCheck(index); //更新修改次数 modCount++; E oldValue = (E) elementData[index]; //移动数据的个数 int numMoved = size - index - 1; if (numMoved > 0) //从elementData[index+1]开始复制numMoved个元素到elementData[index]中 //即elementData[index+1]元素开始索引全部向前移动一位 System.arraycopy(elementData, index+1, elementData, index,numMoved); //数组最后一位设置为空 elementData[--size] = null; // Let gc do its work return oldValue; } /** * 删除ArrayList的指定元素 */ public boolean remove(Object o) { if (o == null) { //为空,遍历删除 for (int index = 0; index < size; index++) if (elementData[index] == null) { fastRemove(index); return true; } } else { //不为空,遍历删除 for (int index = 0; index < size; index++) if (o.equals(elementData[index])) { fastRemove(index); return true; } } return false; } /* * 快速删除第index个元素 */ private void fastRemove(int index) { //更新修改次数 modCount++; //要移动的元素个数 int numMoved = size - index - 1; if (numMoved > 0) //从elementData[index+1]开始复制numMoved个元素到elementData[index]中 //即elementData[index+1]元素开始索引全部向前移动一位 System.arraycopy(elementData, index+1, elementData, index, numMoved); //数组最后一位设置为空 elementData[--size] = null; // Let gc do its work } /** * 清空ArrayList,将全部的元素设为null */ public void clear() { //更新修改次数 modCount++; // Let gc do its work // 设置全部元素为空 for (int i = 0; i < size; i++) elementData[i] = null; //元素个数设置为0 size = 0; } /** * 将集合c追加到ArrayList中 */ public boolean addAll(Collection<? extends E> c) { //获取集合数组 Object[] a = c.toArray(); // 要添加的个数 int numNew = a.length; //判断是否需要扩容 ensureCapacity(size + numNew); // Increments modCount //将a从0开始复制numNew个元素添加到elementData数组size位置开始之后 System.arraycopy(a, 0, elementData, size, numNew); //更新size size += numNew; return numNew != 0; } /** * 从index位置开始,将集合c添加到ArrayList */ public boolean addAll(int index, Collection<? extends E> c) { //索引范围校验 if (index > size || index < 0) throw new IndexOutOfBoundsException( "Index: " + index + ", Size: " + size); //获取集合数组 Object[] a = c.toArray(); //新添加元素的个数 int numNew = a.length; //是否需要扩容 ensureCapacity(size + numNew); // Increments modCount //需要移动的元素个数 int numMoved = size - index; if (numMoved > 0) //移动元素 System.arraycopy(elementData, index, elementData, index + numNew, numMoved); //添加元素 System.arraycopy(a, 0, elementData, index, numNew); //更新size size += numNew; return numNew != 0; } /** * 删除fromIndex到toIndex之间的全部元素。 */ protected void removeRange(int fromIndex, int toIndex) { //更新修改次数 modCount++; //要移动的元素个数 int numMoved = size - toIndex; // 移动元素 System.arraycopy(elementData, toIndex, elementData, fromIndex,numMoved); // Let gc do its work // 移动后剩余的位置设置为空 int newSize = size - (toIndex-fromIndex); while (size != newSize) elementData[--size] = null; } /** * 索引范围检查 */ private void RangeCheck(int index) { //检查数组是否越界 if (index >= size) throw new IndexOutOfBoundsException( "Index: "+index+", Size: "+size); } /** * java.io.Serializable的写入函数 * 将ArrayList的“容量,所有的元素值”都写入到输出流中 */ private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException{ // Write out element count, and any hidden stuff int expectedModCount = modCount; s.defaultWriteObject(); // 输入数组容量 s.writeInt(elementData.length); // 遍历写入数组元素 for (int i=0; i<size; i++) s.writeObject(elementData[i]); //操作过程中ArrayList有修改,抛异常 if (modCount != expectedModCount) { throw new ConcurrentModificationException(); } } /** * java.io.Serializable的读取函数:根据写入方式读出 * 先创建ArrayList,然后根据容量创建数组,最后插入读取的元素值 * 先将ArrayList的“容量”读出,然后将“所有的元素值”读出 */ private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { // Read in size, and any hidden stuff s.defaultReadObject(); // 从输入流中读取ArrayList的“容量” int arrayLength = s.readInt(); Object[] a = elementData = new Object[arrayLength]; // 从输入流中将“所有的元素值”读出 for (int i=0; i<size; i++) a[i] = s.readObject(); } }