中国建设银官方网站,wordpress 源码下载主题,深圳人才市场招聘网最新招聘信息,wordpress登入可见了解 ArrayList
在 Java 中常用集合类之间的关系如下图所示#xff1a; 从图中可以看出 ArrayList 是实现了 List 接口#xff0c;并是一个可扩容数组#xff08;动态数组#xff09;#xff0c;它的内部是基于数组实现的。它的源码定义如下#xff1a;
public class A…了解 ArrayList
在 Java 中常用集合类之间的关系如下图所示 从图中可以看出 ArrayList 是实现了 List 接口并是一个可扩容数组动态数组它的内部是基于数组实现的。它的源码定义如下
public class ArrayListE extends AbstractListEimplements ListE, RandomAccess, Cloneable, java.io.Serializable{
}ArrayList 可以实现所有可选择的列表操作允许所有的元素包括空值。ArrayList 还提供了内部存储 List 的方法它能够完全替代Vector只有一点例外ArrayList 不是线程安全的容器。 ArrayList 有一个容量的概念这个数组的容量size就是 List 用来存储元素的容量。 ArrayList 不是线程安全的容器如果多个线程中至少有两个线程修改了 ArrayList 的结构的话就会导致线程安全问题作为替代条件可以使用线程安全的 List应使用 Collections.synchronizedList List list Collections.synchronizedList(new ArrayList());ArrayList 具有 fail-fast 快速失败机制能够对 ArrayList 作出失败检测。当在迭代集合的过程中该集合在结构上发生改变的时候就有可能会发生 fail-fast即抛出ConcurrentModificationException异常。
通过源码分析 ArrayList 的扩容机制
当使用空参构造器进行创建 ArrayList 的时候实际上给 elementData 初始化赋值的是一个空数组 {}
//数组列表的大小包含的元素数,初始化为 0
private int size;
//存储数组列表元素的数组缓冲区。
transient Object[] elementData;
//默认初始化容量为10
private static final int DEFAULT_CAPACITY 10;
//默认空数组
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA {};
//使用空参构造器创建 ArrayList 时实际上初始化赋值的是一个空数组
public ArrayList() {this.elementData DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}当首次调用 add(E e) 方法进行添加第一个元素时会首先调用 ensureCapacityInternal 方法传入参数 1
//将指定的元素追加到此列表的末尾
public boolean add(E e) {ensureCapacityInternal(size 1); // Increments modCount!!elementData[size] e;return true;
}在 ensureCapacityInternal 方法中会调用 calculateCapacity 方法传入参数为 elementData,1
private void ensureCapacityInternal(int minCapacity) {ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}在 calculateCapacity 方法中判断 elementData 是否为空数组由于是初始化赋值的是一个空数组 {}所以符合 if 条件返回 (DEFAULT_CAPACITY, minCapacity)【10,1】 中大的那个此时返回 10
private static int calculateCapacity(Object[] elementData, int minCapacity) {if (elementData DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {return Math.max(DEFAULT_CAPACITY, minCapacity);}return minCapacity;
}接着返回到 ensureCapacityInternal 方法中继续调用 ensureExplicitCapacity 方法验证是否需要扩容传入参数 10 此时 minCapacity10,elementData.length0 相减小于0执行 grow 方法扩容传入参数 10当添加第2-10个元素时不会执行 grow 方法一直到数组已经满元素时才执行 grow 方法扩容
private void ensureExplicitCapacity(int minCapacity) {modCount;// overflow-conscious codeif (minCapacity - elementData.length 0)grow(minCapacity);
}在 grow 方法中此时 minCapacity10,oldCapacity0,newCapacity0 符合 newCapacity - minCapacity 0 条件执行 newCapacity minCapacity; 不满足 newCapacity - MAX_ARRAY_SIZE 0 执行 Arrays.copyOf() 方法将 elementData 指向的数组中的元素复制到新的数组中新的数组长度为 10并让 elementData 指向新的数组int newCapacity oldCapacity (oldCapacity 1) 完成1.5倍扩容。
private void grow(int minCapacity) {// overflow-conscious codeint 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);
}