7

JDK7 和JDK8的ArrayList的区别对比

 1 year ago
source link: https://blog.51cto.com/learningfish/5996699
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

JDK7 和JDK8的ArrayList的区别对比

精选 原创

爱学习的大鱼 2023-01-08 14:56:57 博主文章分类:Java ©著作权

文章标签 java 初始化 ArrayList 文章分类 Java 编程语言 阅读数202

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;
}
  • 打赏
  • 1
  • 收藏
  • 评论
  • 分享
  • 举报

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK