JDK7 和JDK8的ArrayList的区别对比

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JDK7 和JDK8的ArrayList的区别对比相关的知识,希望对你有一定的参考价值。

示例

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;

以上是关于JDK7 和JDK8的ArrayList的区别对比的主要内容,如果未能解决你的问题,请参考以下文章

关于Jdk7与Jdk8对Collections进行分组的区别

jdk8下 ArrayList与LinedList 排序效率对比

8 arraylist

JDK8:找回 JDK7 查找 javadoc

##(⊙o⊙)值得收藏的JavaSE万字进阶版(⊙o⊙)##JavaSE 高级反射-动态代理-设计模式-JVM篇

ConcurrentHashMap原理,jdk7和jdk8版本