当前位置 : 主页 > 编程语言 > java >

JDK7 和JDK8的ArrayList的区别对比

来源:互联网 收集:自由互联 发布时间:2023-02-04
示例 public class ArrayListTest { public static void main(String[] args) { ArrayListObject jdk = new ArrayList(); jdk.add(123); }} 初始化操作 ①调用无参构造器 jdk7从无参调用有参构造器,并初始化为10: /** * Cons

示例

public class ArrayListTest { public static void main(String[] args) { ArrayList<Object> jdk = new ArrayList<>(); jdk.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源码与jdk8源码不同

jdk7如果加入元素后的个数大于数组长度则扩容(eg.在采用无参构造器初始化,添加到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的容量(eg.jdk8就是采用了该规则,传入minCapacity为10,默认elementData.length为0优化代码),特殊情况2(第二个if)如果扩容后的newCapacity 大于了ArrayList规定的最大值MAX_ARRAY_SIZE 则会传入miniCapacity值采用hugeCapacity方法获取数组大小(尽量不让其出现OutOfMemoryError),jdk7源码与jdk8源码一致

/** * 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); }

④特殊情况源码

private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow throw new OutOfMemoryError(); return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; }
上一篇:加解密与HTTPS(6)
下一篇:没有了
网友评论