ArrayList的实现原理就是大学数据结构书本中的动态数组原理,初始化一个Object数组,然后对Object数组进行插入,扩容,查找,删除等操作。所以可以看出java引用类型所占内存大小是一样的,Object数组类似于c语言中的void*指针数组,每个指针在64位机器上都占8字节, 在hotspot jvm中java引用类型也是占8字节。所以ArrayList无法存放基本类型,只能存放引用类型。以下分析ArrayList最基础,最常用的操作。
首先看ArrayList类关系图
Collection接口继承Iterable接口,所以所有实现了Collection接口的类都支持foreach遍历,List接口继承Collection接口,AbstractCollection接口实现了Collection接口,AbstractList继承AbstractCollection,提供了一些基础操作,如果我们自定义自己的List可以扩展AbstractList抽象类,ArrayList继承AbstractList,并且实现了List接口。这里再引出一个问题,为啥AbstractList实现了List接口,ArrayList是AbstractList的子类再实现一遍,也可以重写父类方法达到同样效果,我觉得是一种编码习惯,并且在对类进行反射操作时,用getInstance方法时子类如果不加implements 父类implements的接口,会获取不到接口。
/* *ArrayList继承AbstractList类,并且实现了List接口 */ public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable { private static final long serialVersionUID = 8683452581122892189L; //默认数组长度10 private static final int DEFAULT_CAPACITY = 10; //初始化化一个空object数组, private static final Object[] EMPTY_ELEMENTDATA = {}; //初始化一个空object数组 private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; //存元素的数组 transient Object[] elementData; // non-private to simplify nested class access //数组大小 private int size; //初始化数组大小的构造方法 public ArrayList(int initialCapacity) { if (initialCapacity > 0) { this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) { this.elementData = EMPTY_ELEMENTDATA; } else { throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); } } //无参构造方法,初始化一个空数组,不指定类型初始化时默认为OBJECT public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; } //初始化一个存在的Collection,不指定类型时为? extends Object, //指定类型后参数必须为E或者E的子类 public ArrayList(Collection<? extends E> c) { //返回一个复制了c中的元素数组引用 //如果c的内部实现使用了Object数组,则返回Object[],否则返回对应数组 elementData = c.toArray(); if ((size = elementData.length) != 0) { //如果不是object数组,则重新将elementData转换为Object[]数组 //如果不转换则会出现运行时报错,比如自定义一个类实现了Collection接口,类 //内部采用Integer[]数组存储元素,然后定义一个ArrayList<Number>对象,如果 //未转换,则这个对象存储Double数据时会抛出ArrayStoreException。 if (elementData.getClass() != Object[].class) elementData = Arrays.copyOf(elementData, size, Object[].class); } else { // replace with empty array. this.elementData = EMPTY_ELEMENTDATA; } } /** * 确定数组容量,minCapacity表示所必须的最小容量 */ private void ensureCapacityInternal(int minCapacity) { //如果elementData是默认容量空数组,则选择默认容量和最小容量较大的一个 //做为最小容量 if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); } ensureExplicitCapacity(minCapacity); } private void ensureExplicitCapacity(int minCapacity) { modCount++; //list修改次数+1 //如果数组长度小于所需的最小容量,则扩容 if (minCapacity - elementData.length > 0) grow(minCapacity); } //arraylist最大个数 private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; //arraylist满之后,对Object数组扩容 private void grow(int minCapacity) { // 原数组大小 int oldCapacity = elementData.length; //新的大小为原来的3倍 int newCapacity = oldCapacity + (oldCapacity >> 1); //如果传进的参数大于扩容的参数,则按照传进的参数确定数组大小 if (newCapacity - minCapacity < 0) newCapacity = minCapacity; //如果扩容的参数大于数组最大容量 if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); //获取一个新的扩容数组,并将原有元素复制到新数组 elementData = Arrays.copyOf(elementData, newCapacity); } private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow throw new OutOfMemoryError(); return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; } /** * 返回list大小,也就是Object数组大小 */ public int size() { return size; } /** * 判断数组是否为空 */ public boolean isEmpty() { return size == 0; } /** * 数组是否包含指定元素 */ public boolean contains(Object o) { return indexOf(o) >= 0; } /** * 返回元素所在数组的下标,从前往后搜索,如果找不到则返回-1 */ public int indexOf(Object o) { //如果是null元素则只返回第一个为null的下标 if (o == null) { for (int i = 0; i < size; i++) if (elementData[i]==null) return i; } else { //返回第一个为elementData[i]的下标 for (int i = 0; i < size; i++) if (o.equals(elementData[i])) return i; } return -1; } /** * 返回元素所在数组的下标,从后往前搜索,如果找不到则返回-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; } /** * 复制一个新的list */ 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 throw new InternalError(e); } } /** * 复制elementData数组,返回一个新的Object[]对象 */ public Object[] toArray() { return Arrays.copyOf(elementData, size); } /** * 泛型方法,将elementData复制为T[]类型数组 */ @SuppressWarnings("unchecked") public <T> T[] toArray(T[] a) { //如果a的长度小于elementData长度调用copyOf,新创建一个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()); //如果小于等于则,直接复制到a数组 System.arraycopy(elementData, 0, a, 0, size); if (a.length > size) a[size] = null; return a; } // 获取指定下标的元素 @SuppressWarnings("unchecked") E elementData(int index) { return (E) elementData[index]; } /** * 获取指定index的元素 */ public E get(int index) { rangeCheck(index); return elementData(index); } /** * 设置指定index的元素 */ public E set(int index, E element) { rangeCheck(index); E oldValue = elementData(index); elementData[index] = element; return oldValue; } /** * 在list尾部添加元素 */ public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; } /** * 移除指定位置的元素 */ public E remove(int index) { rangeCheck(index); modCount++; E oldValue = elementData(index); 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 return oldValue; } /** * 从前往后移除第一个和o相等的元素 */ 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; } /* * 移除 减少了边界检查 */ private void fastRemove(int index) { modCount++; int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; //gc的时候会将elementData[i]指向的堆内存释放掉 } /** * 将集合对象c添加到list末尾 */ public boolean addAll(Collection<? extends E> c) { Object[] a = c.toArray(); int numNew = a.length; ensureCapacityInternal(size + numNew); // Increments modCount System.arraycopy(a, 0, elementData, size, numNew); size += numNew; return numNew != 0; } /** * 数组边界检查 */ private void rangeCheck(int index) { if (index >= size) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } /** * 返回ListIterator迭代器,起始迭代位置是index */ public ListIterator<E> listIterator(int index) { if (index < 0 || index > size) throw new IndexOutOfBoundsException("Index: "+index); return new ListItr(index); } /** * 返回ListIterator迭代器,起始迭代位置是0 */ public ListIterator<E> listIterator() { return new ListItr(0); } /** * 返回Iterator迭代器,起始位置是0 */ public Iterator<E> iterator() { return new Itr(); } /** * 私有内部类实现Iterator接口,使用Iterator遍历list,可以在遍历的过程中删除元素 */ private class Itr implements Iterator<E> { int cursor; // 数组当前游标 int lastRet = -1; // 初始化-1,遍历开始后等于最后一次读取位置的下标 int expectedModCount = modCount;//期望修改次数 //判断是否迭代完 public boolean hasNext() { return cursor != size; } /** * 返回当前元素 */ @SuppressWarnings("unchecked") public E next() { //期望修改次数和实际修改次数是否相等 checkForComodification(); int i = cursor; if (i >= size) throw new NoSuchElementException(); Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length) throw new ConcurrentModificationException(); cursor = i + 1; return (E) elementData[lastRet = i]; // } /** * 移除最后一次遍历的位置的元素,如果连续调用remove则会出错,必须调用next()后才能调用remove */ public void remove() { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { ArrayList.this.remove(lastRet); cursor = lastRet; //游标等于移除的位置 lastRet = -1; //最后一次遍历的位置重置-1 expectedModCount = modCount; //给期望修改的次数重新赋值 } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } } /** * ListIterator的实现类,主要实现了对list从后往前进行迭代,并且在迭代过程中 * 可以添加和修改元素 */ private class ListItr extends Itr implements ListIterator<E> { ListItr(int index) { super(); cursor = index; } //判断是否有前驱元素 public boolean hasPrevious() { return cursor != 0; } //返回下一个要迭代的元素位置 public int nextIndex() { return cursor; } //返回从后往前将要遍历的元素下标 public int previousIndex() { return cursor - 1; } //返回cursor前一个元素 @SuppressWarnings("unchecked") public E previous() { checkForComodification(); int i = cursor - 1; if (i < 0) throw new NoSuchElementException(); Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length) throw new ConcurrentModificationException(); cursor = i; return (E) elementData[lastRet = i]; } public void set(E e) { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { ArrayList.this.set(lastRet, e); } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } //在当前游标指定的位置添加元素 public void add(E e) { checkForComodification(); try { int i = cursor; ArrayList.this.add(i, e); cursor = i + 1; //添加完游标加一,从前往后遍历时刚添加的不会遍历到,从后往前会遍历到刚添加的 lastRet = -1; //重置lastRet expectedModCount = modCount; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } }