本博客仅为个人工作学习使用,如有差错欢迎交流指正。
包含四方面内容:1.类继承结构 2.属性字段 3.构造方法 4.常见函数
ArrayList 继承关系:
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable
对应的类图:
root 接口是Collection<E> ,它继承了 Iterable<E> 迭代器接口,调用 Iterator<T> iterator() 会返回对应的遍历迭代器。
抽象类AbstractCollection <E>实现了Collection<E>,List<E> 接口继承了Collection<E>。
抽象类AbstractList<E>继承了AbstractCollection <E>,实现了List<E>
最终的实现类ArrayList<E> 继承了AbstractList<E>类,实现了Serializable(序列化),Clonable(接口),RandomAccess(随机访问)三个接口。
ArrayList 有7个字段,
含义:序列化版本id,默认容量等于10,空Object[]数组,默认容量的空数组,保存数据的elementData 数组,数组实际length,最大数组规模
ArrayList 内部持有 Object[] elementData 数组来保存数据,构造函数有三个
1.没有指定容量,使用空的构造函数,用默认容量的空数组
public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; }
2.指定初始容量,判断initialCapacity 值
public ArrayList(int initialCapacity) { if (initialCapacity > 0) { //大于0,创建长度为容量大小的数组 this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) { //等于0,使用非默认容量空数组 this.elementData = EMPTY_ELEMENTDATA; } else { //小于0,抛IllegalArgumentException throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); } }
3.传入集合类型数据
public ArrayList(Collection<? extends E> c) { elementData = c.toArray(); //首先将Collection 转化为对应数组 if ((size = elementData.length) != 0) { //包含元素 // c.toArray might (incorrectly) not return Object[] (see 6260652) if (elementData.getClass() != Object[].class) //class 类型是否一致 elementData = Arrays.copyOf(elementData, size, Object[].class); //调用Arrays 复制方法,参数1 源数组,参数2 要复制的长度 参数3 目的数组的类型 } else { //长度为0,不包含元素 // replace with empty array. this.elementData = EMPTY_ELEMENTDATA; } }
Arrays.copyOf 追踪
调用本地native方法
对ArrayList 的 add及delete等操作都依赖于以上两个函数。
内部有两个迭代器类
1.private class ListItr extends Itr implements ListIterator<E>
2.private class Itr implements Iterator<E>
通过返回元素的下标和最近一次返回元素的下标来遍历
常见add,remove,grow 函数
1.add添加元素到list末尾
public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! 容量判断,不满足最小容量要求则扩容 elementData[size++] = e; return true; }
2.add指定下标
public void add(int index, E element) { rangeCheckForAdd(index); //判断下标数值 ensureCapacityInternal(size + 1); // Increments modCount!! System.arraycopy(elementData, index, elementData, index + 1, size - index);//复制原有的其他下标数据 elementData[index] = element; size++; }
3.remove 指定下标,返回旧的值
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; }
4.remove 指定元素值
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; // clear to let GC do its work }
具体grow 扩容函数
private void grow(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); }