1)ArrayList 特点
- List 接口的可变数组实现,ArrayList 允许使用任何元素,包括 null。
- ArrayList 和 Vector 基本类似,只不过 Vector 是线程安全的,ArrayList 是线程不安全的。
- size、isEmpty、get、set、iterator 和 listIterator 以常量时间运行,其他的操作基本以线性时间运行。
- 每个 ArrayList 都有一个容量,容量表示该 ArrayList 当前能容纳的元素个数,随着元素的增加,ArrayList 会自动扩容。
- 在创建 ArrayList 时可以指定一个合适的初始化容量,以减少频繁扩容带来的性能损耗。
- ArrayList 是线程不安全的,多线程并发访问 ArrayList 并且至少有一个线程修改了它的结构【增加、删除元素、扩容等】,
则 ArrayList 将抛出 ConcurrentModificationException 异常。 - 快速失败机制:iterator 和 listIterator 返回的迭代器是快速失败的,如果不是通过 ListIterator#remove() 或 ListIterator#add(Object) 方法修改其结构,
则 ArrayList 将尽最大努力抛出 ConcurrentModificationException 异常。 - ArrayList 的缩容机制:通过 trimToSize 方法将 ArrayList 的容量缩小为当前元素的个数,以减少 ArrayList 的内存占用。
- ArrayList 的扩容机制:默认为 1.5 倍向下取整扩容,如果批量添加元素,则以 size+newNum 进行扩容。
2)创建实例
transient Object[] elementData; private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; public ArrayList() { this.elementData = ArrayList.DEFAULTCAPACITY_EMPTY_ELEMENTDATA; } public ArrayList(int initialCapacity) { if (initialCapacity > 0) { this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) { this.elementData = ArrayList.EMPTY_ELEMENTDATA; } else { throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); } } public ArrayList(Collection<? extends E> c) { this.elementData = c.toArray(); if ((this.size = this.elementData.length) != 0) { if (this.elementData.getClass() != Object[].class) { this.elementData = Arrays.copyOf(this.elementData, this.size, Object[].class); } } else { this.elementData = ArrayList.EMPTY_ELEMENTDATA; } }
3)在尾部添加元素
protected transient int modCount = 0; @Override public boolean add(E e) { modCount++; this.add(e, this.elementData, this.size); return true; } private void add(E e, Object[] elementData, int s) { if (s == elementData.length) { elementData = this.grow(); } elementData[s] = e; this.size = s + 1; } private Object[] grow() { return this.grow(this.size + 1); } private Object[] grow(int minCapacity) { return this.elementData = Arrays.copyOf(this.elementData, this.newCapacity(minCapacity)); } private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; private int newCapacity(int minCapacity) { final int oldCapacity = this.elementData.length; final int newCapacity = oldCapacity + (oldCapacity >> 1); if (newCapacity - minCapacity <= 0) { if (this.elementData == ArrayList.DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { return Math.max(ArrayList.DEFAULT_CAPACITY, minCapacity); }