ArrayList初始化长度的作用及影响

ArrayList初始化长度的作用及影响平时写代码都直接写 List String list newArrayList lt gt 由于公司做政府项目 对并发和响应没有太苛刻的要求 平时就没有考虑到这一块 今天看同事代码在 newArrayList lt gt 的时候带入初始容量 于是好奇百度一下 讲结果记录下来 一 有无初始容量的区别 Themaximumsi SomeVMsreser String

平时写代码都直接写

List<String> list = new ArrayList<>(); 

由于公司做政府项目,对并发和响应没有太苛刻的要求,平时就没有考虑到这一块。今天看同事代码在new ArrayList<>()的时候带入初始容量,于是好奇百度一下,讲结果记录下来。

一、有无初始容量的区别

 / * The maximum size of array to allocate. * Some VMs reserve some header words in an array. * Attempts to allocate larger arrays may result in * OutOfMemoryError: Requested array size exceeds VM limit */ private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; / * Default initial capacity. */ private static final int DEFAULT_CAPACITY = 10; / * The array buffer into which the elements of the ArrayList are stored. * The capacity of the ArrayList is the length of this array buffer. Any * empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA * will be expanded to DEFAULT_CAPACITY when the first element is added. */ transient Object[] elementData; // non-private to simplify nested class access / * Shared empty array instance used for empty instances. */ private static final Object[] EMPTY_ELEMENTDATA = { 
   }; / * 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) { 
    if (initialCapacity > 0) { 
    this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) { 
    this.elementData = EMPTY_ELEMENTDATA; } else { 
    throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); } } / * 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); } 

以上是JDK1.8的ArrayList源码,可以看出,

  1. 没有初始容量的话,在做数据操作的时候ArrayList会自己创建容量,JDK1.8默认为10
  2. 每次扩容后容量为oldCapacity + (oldCapacity >> 1)
  3. 容量最大值Integer.MAX_VALUE – 8

由此可以想到,如果存在上千上万数据量的操作,不初始容量和初始化了合适的容量,处理时间肯定不同,因为初始化和扩容是需要时间的。

测试代码如下:

public static void main(String[] args) { 
    final int count = 200 * 10000; List<Integer> list = new ArrayList<>(); long begin = System.currentTimeMillis(); for(int i = 0; i < count ; i++) { 
    list.add(i); } System.out.println("没有设置ArrayList初始容量: " + (System.currentTimeMillis() - begin) + " ms"); List<Integer> list2 = new ArrayList<>(10); long begin2 = System.currentTimeMillis(); for(int i = 0; i < count ; i++) { 
    list2.add(i); } System.out.println("设置了ArrayList初始容量: " + (System.currentTimeMillis() - begin2) + " ms"); } 

输出:

没有设置ArrayList初始容量: 96 ms 设置了ArrayList初始容量: 26 ms 
/ * Appends the specified element to the end of this list. * * @param e element to be appended to this list * @return true (as specified by {@link Collection#add}) */ public boolean add(E e) { 
    ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; } 

进入方法:

private void ensureCapacityInternal(int minCapacity) { 
    ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); } 

再往下:

private static int calculateCapacity(Object[] elementData, int minCapacity) { 
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { 
   // 第一次add的时候,都会走这一步 return Math.max(DEFAULT_CAPACITY, minCapacity);//初始化容量小于默认值10都会取10,反之取自定义的容量 } return minCapacity; } 

扩容方法:

private void ensureExplicitCapacity(int minCapacity) { 
    modCount++; // overflow-conscious code if (minCapacity - elementData.length > 0) grow(minCapacity); } 

grow():

/ * 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) { 
   //minCapacity是当前容量,比如,默认容量下,add一次后就是10+1 // 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); } 

总结:

  1. 建议初始化容量,减少系统初始化容量的耗时;
  2. 初始化容量不是越大越好,跟系统配置相关,因为要开辟内存。如果能确定add的总数,以总数作为初始容量效率最高,但这种场景太少了。最佳的设置要兼顾内存空间和扩容次数,我也没有找到最优解,欢迎大佬补充。
  3. 尽管不知道初始化多少最快,但是初始化比未初始化快,并且有限的数据量下,设置不同initialCapacity的差距不大。最终,我建议大家初始化容量,并且就写10(<=10都一样,看自己喜好)

上例不同大小初始容量的耗时:

initialCapacity time
未初始化 96
<=10 26
100 26
1000 23
10000 648
24
18
609

二、initialCapacity != list.size()

public static void main(String[] args) { 
    List<Integer> list = new ArrayList<>(10); list.set(0, 666); } 

console:

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 at java.util.ArrayList.rangeCheck(ArrayList.java:657) at java.util.ArrayList.set(ArrayList.java:448) at top.chengsw.demo.test.ListTest.main(ListTest.java:25) 
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/224494.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 上午11:48
下一篇 2026年3月17日 上午11:48


相关推荐

  • 华为模拟器eNSP安装史上最全。。

    华为模拟器eNSP安装史上最全。。**华为模拟器基本使用**首先下载模拟工具eNSPeNSP(EnterpriseNetworkSimulationPlatform)是一款由华为提供的免费的、可扩展的、图形化操作的网络仿真工具平台,主要对企业网络路由器、交换机进行软件仿真,完美呈现真实设备实景,支持大型网络模拟,让广大用户有机会在没有真实设备的情况下能够模拟演练,学习网络技术。网站地址https://supp…

    2022年6月16日
    36
  • 如何在电脑上画漫画 0基础_零基础学电脑快速入门

    如何在电脑上画漫画 0基础_零基础学电脑快速入门零基础怎么学漫画手绘?手绘漫画入门教程!想要创作手绘漫画,最重要的并不是画工技术,最重要的是学会如何讲故事,学习如何画分镜,提升个人在视频艺术方面的审美观,顺便一提,实际上天赋也是很重要的一点。当一个人的审美观达到一定程度时,对于创作本身理解的思维差异便于一般人不同了,一般人以为创作很简单,并不知道创作的难点,以为创作就是想写什么就写什么。日本画师Aちき的作品如果大家想要学习绘画的话,可…

    2022年8月29日
    6
  • Linux 安装JDK详细步骤

    Linux 安装JDK详细步骤Linux 系统上一般会安装好 OpenJDK 所以安装 JDK 之前 需要卸载系统自带的 OpenJDK 以及相关的 Java 文件 一 卸载系统自带的 OpenJDK 以及相关的 Java 文件 1 查看 Java 信息以及相关的 Java 文件查看 JDK 信息 输入 java version 检测 jdk 的安装包 输入 rpm qa grepjava2 接着删除相关 Java 文件 并检查是否删除完即可删除输入 rpm enodeps 包名检查是否删除完 输入 rpm qa

    2026年3月16日
    2
  • YUI Compressor插件压缩后war中的js/css文件未压缩的解决方法(被maven打包顶替了)

    YUI Compressor插件压缩后war中的js/css文件未压缩的解决方法(被maven打包顶替了)YUICompressorMaven插件可以压缩/合并js或css文件,经常用在Maven项目中,但最近发现在wabapp中执行了mvninstall命令进行发布之后,终端中显示插件已经执行了压缩的动作,但在输出文件夹或者war包中js和css文件都还是未压缩的原始文件。这样执行mvninstall命令之后发现虽然执行了压缩任务,但是在目标目录下和war包中的js和css…

    2022年7月18日
    24
  • native2ascii java_Native2Ascii和Ascii2Native的Java实现

    native2ascii java_Native2Ascii和Ascii2Native的Java实现packageutil;/***native2ascii.exeJavacodeimplementation.**@author*@version1.0*/publicclassNative2AsciiUtils{/***prefixofasciistringofnativecharacter*/privatestaticStringPREFIX=”\…

    2025年8月31日
    5
  • pandas读取csv文件的操作

    pandas读取csv文件的操作1 读取 csv 文件 importpandas 读取整个 csv 文件 csv data pd read csv stock day csv 读取指定列索引字段的数据 csv data pd read csv stock day csv usecols open close 将我们修改

    2026年3月19日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号