ArrayList的源码分析(基于jdk1.8)
Posted duoduotouhenying
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ArrayList的源码分析(基于jdk1.8)相关的知识,希望对你有一定的参考价值。
1.初始化
transient Object[] elementData; //实际存储元素的数组 private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; public ArrayList() { //初始化为一个默认的空数组 this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; }
2. 添加元素
private static final int DEFAULT_CAPACITY = 10;//默认容量 public boolean add(E e) { //确保当前数组的容量是够得 ensureCapacityInternal(size + 1); // Increments modCount!! //将新元素添加到[size++]的位置 elementData[size++] = e; return true; }
private void ensureCapacityInternal(int minCapacity) { //如果是第一次添加 if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { //扩容为默认容量大小:10 minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); } //每一次添加都要判断是否需要扩容 ensureExplicitCapacity(minCapacity); }
3.扩容
private void ensureExplicitCapacity(int minCapacity) { modCount++; // 如果需要扩容 if (minCapacity - elementData.length > 0) grow(minCapacity); } 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); }
4.结论
ArrayList物理结构是数组,决定了它的存储特点是:需要开辟连续的存储空间来存储元素,当存储容量不够时,需要扩容,增加容量为原来的1.5倍。类似的,Vector的物理结构也是数组,当存储容量不够时,需要扩容为原来的2倍。那么是1.5倍好呢?还是2倍好呢?1.5倍使得数组空间使用率提高了,但是这也增加了扩容的频率。所以,建议大家在选择动态数组时,如果对要存储的元素个数有一个预估时,那么可以在创建ArrayList时,就使用ArrayList(int initialCapacity) 构造器,避免反复扩容。
以上是关于ArrayList的源码分析(基于jdk1.8)的主要内容,如果未能解决你的问题,请参考以下文章