ArrayList是一个非线程安全的有序集合, 按照添加顺序排列, 能够随机添加或删除元素, 支持任意类型元素, 支持泛型。java
对于ArrayList, JDK1.8相对于JDK1.9没有什么大变化, JDK1.8版本比JDK1.7版增长了一些函数编程特性方法, 以下编程
//循环每一个元素, 以元素为参数执行action操做 @Override public void forEach(Consumer<? super E> action) { ... } //经过Predicate(断言函数接口)实现过滤删除 @Override public boolean removeIf(Predicate<? super E> filter) { Objects.requireNonNull(filter); .... return anyToRemove; } //经过UnaryOperator(一元操做函数接口)来实现替换 @Override @SuppressWarnings("unchecked") public void replaceAll(UnaryOperator<E> operator) { ... }
/** * The array buffer into which the elements of the ArrayList are stored. * The capacity of the ArrayList is the length of this array buffer. Any * empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA * will be expanded to DEFAULT_CAPACITY when the first element is added. */ transient Object[] elementData; // non-private to simplify nested class access
从以上源码能够看出:数组
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); } } /** * Constructs an empty list with an initial capacity of ten. */ public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; } public ArrayList(Collection<? extends E> c) { elementData = c.toArray(); if ((size = elementData.length) != 0) { // c.toArray might (incorrectly) not return Object[] (see 6260652) if (elementData.getClass() != Object[].class) elementData = Arrays.copyOf(elementData, size, Object[].class); } else { // replace with empty array. this.elementData = EMPTY_ELEMENTDATA; } }
ArrayList实例化有如下三种:安全
private void grow(int minCapacity) { //旧容量 int oldCapacity = elementData.length; //计算新容量 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; }
扩容经过grow()方法实现, 主要作了如下三项工做:数据结构
/** * 添加一个元素, 支持任何类型 * */ public boolean add(E e) { //确保内部容量能够支持添加的元素 ensureCapacityInternal(size + 1); //向数组中添加元素 elementData[size++] = e; return true; } /** * 将元素添加到特定的索引位置 * * @param index 待添加元素的索引 * @param element 待添加元素 * @throws IndexOutOfBoundsException {@inheritDoc} */ public void add(int index, E element) { //检查index是否超出数组的index限制,若是超过, //则抛出数组越界异常(IndexOutOfBoundsException) rangeCheckForAdd(index); //确保内部容量能够支持添加的元素 ensureCapacityInternal(size + 1); //复制一个新数组, 目的是为了移位,将插入点index以后的元素日后移动 System.arraycopy(elementData, index, elementData, index + 1, size - index); elementData[index] = element; size++; } //确保内部容量能够支持添加的元素 private void ensureCapacityInternal(int minCapacity) { //若是数组为空, 多是单元素添加或批量元素添加触发当前操做 //单元素添加: minCapacity = DEFAULT_CAPACITY(至关于初始化默认容量) //批量元素添加: minCapacity不变 if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); } //确保准确的容量 ensureExplicitCapacity(minCapacity); } //确保准确的容量 private void ensureExplicitCapacity(int minCapacity) { //解决并发问题的,后续会提到 modCount++; // elementData新增元素后, 若是当前容量不能知足elementData的长度, 则进行扩容 if (minCapacity - elementData.length > 0) grow(minCapacity); }
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; } public boolean remove(Object o) { if (o == null) { //查找为null的元素, 并删除 for (int index = 0; index < size; index++) if (elementData[index] == null) { fastRemove(index); return true; } } else { //查找不为null的元素,并删除 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) //将元素向前移位 System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // clear to let GC do its work }
/** * Returns the element at the specified position in this list. * * @param index index of the element to return * @return the element at the specified position in this list * @throws IndexOutOfBoundsException {@inheritDoc} */ public E get(int index) { rangeCheck(index); return elementData(index); }
ArrayList的 add, remove,get操做都没有加锁, 因此是非线程安全的。并发
protected transient int modCount = 0; 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++; } 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; }
这个变量充斥着整个ArrayList类中, 凡有修改的地方就有他它, 它记录着ArrayList元素修改次数。ide
下面来讲明它的用处:函数
//迭代器 public ListIterator<E> listIterator(final int index) { //检查修改状态(modCount) checkForComodification(); rangeCheckForAdd(index); final int offset = this.offset; return new ListIterator<E>() { @SuppressWarnings("unchecked") public E next() { checkForComodification(); ...... } public void remove() { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { ...... } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } public void add(E e) { checkForComodification(); try { ...... } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } final void checkForComodification() { //若是不相等, 说明其余线程修改了ArrayList元素 if (expectedModCount != ArrayList.this.modCount) throw new ConcurrentModificationException(); } ...... }; }
能够看出在ListIterator迭代器中, 进行任何操做都会调用checkForComodification() 检查modCount是否有变更, 若是有变更, 就表明其余线程修改了ArrayList的元素,而后抛出ConcurrentModificationException异常.性能
它的做用是用于实现快速失败机制(fail-fast), 当咱们对ArrayList的元素迭代时, 若是其它线程修改了某个元素, 会产生迭代结果会不正确或迭代失败, 快速失败机制能够提早检测迭代失败问题, 避免浪费时间, 影响性能。ui