ArrayList在jdk7和jdk8中有什么不同呢?
下文笔者讲述Arraylist在jdk7和jdk8之间的区别说明,如下所示
例调用add(E e)方法
例
public class ArrayListTest { public static void main(String[] args) { ArrayList<Object> arrayList = new ArrayList<>(); arrayList.add(123); } }
初始化操作
调用无参构造器
jdk7从无参调用有参构造器,并初始化为10: /** * Constructs an empty list with an initial capacity of ten. */ public ArrayList() { this(10); } /** * Constructs an empty list with the specified initial capacity. * * @param initialCapacity the initial capacity of the list * @throws IllegalArgumentException if the specified initial capacity * is negative */ public ArrayList(int initialCapacity) { super(); if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); this.elementData = new Object[initialCapacity]; } jdk8将其定义为长度为零的空数组,在之后的add方法中初始化大小(懒加载模式) /** * Shared empty array instance used for default sized empty instances. We * distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when * first element is added. */ private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; /** * Constructs an empty list with an initial capacity of ten. */ public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; }
添加操作
调用add(E e)方法
jdk7源码与jdk8源码一致
/** * Appends the specified element to the end of this list. * * @param e element to be appended to this list * @return <tt>true</tt> (as specified by {@link Collection#add}) */ public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; }
调用ensureCapacityInternal(int minCapacity)方法
jdk7 当加入元素后的个数大于数组长度则扩容 (在采用无参构造器初始化 添加到11个元素时会扩容 private void ensureCapacityInternal(int minCapacity) { modCount++; // overflow-conscious code if (minCapacity - elementData.length > 0) grow(minCapacity); } jdk8 当采用时默认初始化则数组elementData为DEFAULTCAPACITY_EMPTY_ELEMENTDATA 而第一次调用add时 minCapacity为1,DEFAULT_CAPACITY为10 minCapacity取两个中的最大值10 然后调用ensureExplicitCapacity会将数组elementData会 在添加第一个元素时初始化大小为10 /** * Default initial capacity. */ private static final int DEFAULT_CAPACITY = 10; private void ensureCapacityInternal(int minCapacity) { if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); } ensureExplicitCapacity(minCapacity); } private void ensureExplicitCapacity(int minCapacity) { modCount++; // overflow-conscious code if (minCapacity - elementData.length > 0) grow(minCapacity); }
扩容方式不同
通过情况下(不进行if检测时) 则扩容为1.5倍 特殊情况1: (第一个if)当newCapacity<minCapacity时采用minCapacity的容量 (例:jdk8就是采用了该规则,传入minCapacity为10,默认elementData.length为0优化代码) 特殊情况2: (第二个if)当扩容后的newCapacity 大于了ArrayList规定的最大值MAX_ARRAY_SIZE 则会传入miniCapacity值采用hugeCapacity方法获取数组大小(尽量不让其出现OutOfMemoryError)
/** * Increases the capacity to ensure that it can hold at least the * number of elements specified by the minimum capacity argument. * * @param minCapacity the desired minimum capacity */ 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); }
从JDK以上的源码分析 我们可以得出ArrayList在JDK7和JDK8中的区别是: 1.初始化不同 2.扩容方式不同 其他的操作方式,可以说两者基本一致
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。