首页 > 其他分享 >JDK7 和JDK8的ArrayList的区别对比

JDK7 和JDK8的ArrayList的区别对比

时间:2023-01-08 15:00:23浏览次数:47  
标签:capacity int ArrayList elementData private minCapacity JDK8 JDK7 源码

示例

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;
}

标签:capacity,int,ArrayList,elementData,private,minCapacity,JDK8,JDK7,源码
From: https://blog.51cto.com/learningfish/5996699

相关文章

  • ArrayList的二进制序列化及反序列化实现
    usingSystem;usingSystem.Collections.Generic;usingSystem.Collections;usingSystem.Text;usingSystem.Data;usingSystem.Data.SqlClient;usingSystem.IO;us......
  • JAVA问题总结之22--Arraylist集合的操作
    JAVA问题总结之22--Arraylist集合的操作:packagecom.atguigu.java1;importjava.util.ArrayList;importjava.util.List;importorg.junit.Test;publicclassTestList{......
  • 比较ArrayList与LinkedList
    比较ArrayList与LinkedList底层实现ArrayList是数组-顺序表LinkedList是双向链表增加第一条数据时LinkedList的更快因为ArrayList默认初始化时创建容量为10的数组空......
  • 03-ArrayList(CustomDynamicArray)
    数据结构是什么?..动态数组...Person.javapackagecom.rnny;/***@author软柠柠吖(Runny)*@date2023-01-03*/publicclassPerson{privateStrin......
  • 集合2 ArrayList
    ArrayListpublicclassList{publicstaticvoidmain(String[]args){//TODOArrayList:Array+List//List:列表,清单--按照数据插入......
  • JDK8的安装和配置
    卸载JDK目前大部分公司所用的都是JDK8,在此分享一下已安装的JDK的卸载方法删除JDK的安装目录在开始中打开设置找到应用之后卸载jdk在系统的环境变量中删除与Java......
  • java中的ArrayList的add()源码解析
    使用无参构造器创建的ArrayList对象,示例代码如下:publicclassArrayListTest{publicstaticvoidmain(String[]args){Listlist=newArrayList();......
  • Java-常用API(String、ArrayList) 7-笔记
    什么是api?全称应用程序编程接口,就是Java自己写好的程序,给程序员调用的,方便完成一些功能的。API文档程序使用说明书String是什么?String是字符串类型,它定义的变量可以指向一......
  • JDK8下载安装与配置环境变量(linux)
    一、JDK8下载官网下载地址:JavaDownloads|Oracle下载前需登录Oracle账号,没有的话可以用邮箱注册一个,登录之后即可进行下载。二、JDK8安装1.将安装包上传至服务器的......
  • 获取ArrayList容量的方法
    通过反射获取ArrayList的容量publicstaticintgetArrayListLength(ArrayList<String>list)throwsException{//获取class对象Class<?>arraylist=Class.......