问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

ArrayList默认容量10的秘密大揭秘!

创作时间:
作者:
@小白创作中心

ArrayList默认容量10的秘密大揭秘!

引用
CSDN
12
来源
1.
https://blog.csdn.net/m0_67322837/article/details/124322953
2.
https://blog.csdn.net/qq_30757161/article/details/138401207
3.
https://cloud.baidu.com/article/3310715
4.
https://cloud.baidu.com/article/3311779
5.
https://blog.csdn.net/qq_41594146/article/details/81870931
6.
https://blog.csdn.net/agonie201218/article/details/125318529
7.
https://blog.csdn.net/xx12321q/article/details/122774799
8.
https://m.toutiao.com/article/7080504543628263944/
9.
https://www.cnblogs.com/huangzhe1515023110/articles/9276049.html
10.
https://www.bilibili.com/read/cv17285223/
11.
https://my.oschina.net/emacs_8882080/blog/17500477
12.
https://www.cnblogs.com/shakinghead/p/7717249.html

在Java开发中,ArrayList是我们最常用的集合类之一。当我们创建一个ArrayList实例时,如果不指定初始容量,它的默认容量是10。这个看似普通的数字背后,其实蕴含着Java集合框架设计者的深思熟虑。为什么选择10作为默认容量?这个决策背后有哪些性能和内存使用的考量?让我们一起来揭秘这个看似简单却至关重要的设计细节。

01

ArrayList的底层实现揭秘

ArrayList是基于动态数组实现的,它允许我们像操作数组一样通过索引访问元素,同时又具备动态调整大小的能力。当我们通过new ArrayList<>()创建一个ArrayList实例时,实际上创建的是一个空数组,即数组的长度为0。

public ArrayList() {
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

这里的DEFAULTCAPACITY_EMPTY_ELEMENTDATA是一个空数组,长度为0。但是,当我们第一次调用add()方法添加元素时,ArrayList会自动扩容到默认容量10。

private static final int DEFAULT_CAPACITY = 10;

这个默认容量的选择并不是随意的,而是经过精心设计的。

02

为什么选择10作为默认容量

性能优化的考量

ArrayList在添加元素时会检查当前容量是否足够。如果容量不足,它会创建一个新的数组,新数组的容量是原数组容量的1.5倍,然后将原数组中的元素复制到新数组中。这个过程称为扩容,涉及内存分配和元素复制,是一个相对耗时的操作。

如果默认容量设置得太小,比如1或2,那么在添加少量元素后就会频繁触发扩容操作,导致性能下降。相反,如果默认容量设置得过大,比如100或1000,而实际使用的元素数量远小于这个值,就会造成内存的浪费。

内存使用的平衡

将默认容量设置为10,意味着在创建ArrayList对象时,会预先分配一个能够容纳10个元素的数组。这样做的好处是可以减少在添加少量元素时的扩容次数,提高性能。同时,由于ArrayList是基于数组实现的,预先分配内存可以确保数组在内存中的连续性,有利于CPU缓存的使用,进一步提高性能。

然而,预先分配的内存并不是越多越好。如果我们将初始化容量设置得过大,而实际使用的元素数量远小于这个值,那么就会造成内存的浪费。因此,在选择初始化容量时,我们需要根据实际应用的需求进行权衡。

编程习惯的影响

除了性能优化和内存使用外,将ArrayList的初始化容量设置为10还受到编程习惯的影响。在实际开发中,我们往往需要根据实际需求来设置ArrayList的初始化容量。而10作为一个适中的值,既可以满足大部分情况下的需求,又可以作为一个默认值方便我们在创建ArrayList对象时直接使用。

03

ArrayList的扩容机制

ArrayList的容量不足以容纳新元素时,它会进行扩容操作。扩容过程如下:

  1. 计算新容量:新容量是当前容量的1.5倍(即oldCapacity + (oldCapacity >> 1)
  2. 创建新数组:分配一个新数组,大小为计算出的新容量
  3. 复制元素:将原数组中的所有元素复制到新数组中
  4. 更新引用:将elementData引用指向新数组

这个过程虽然保证了ArrayList的动态性,但频繁的扩容操作会带来性能开销。特别是当数据量较大时,每次扩容都需要复制所有元素,这会显著影响程序的执行效率。

04

最佳实践建议

为了优化ArrayList的使用,提高程序性能,建议在创建ArrayList时根据预期的元素数量指定初始容量。例如,如果我们知道将要存储大约1000个元素,可以直接创建一个初始容量为1000的ArrayList

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

这样可以避免多次扩容带来的性能损失。当然,如果无法预知元素数量,使用默认容量10也是一个合理的选择。

通过理解ArrayList的底层实现和设计原理,我们可以更合理地使用这个强大的集合类,写出更高效、更优化的代码。记住,每个看似简单的默认值背后,都凝聚着设计者对性能、内存和使用习惯的深思熟虑。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号