再也不敢使用集合默认初始化值了


阿里开发规范中说明
本文就来聊聊很多时候大家都喜欢使用集合的默认初始化大小,然后怎么掉进坑里的。
概述
集合初始化通常进行分配容量、设定特定参数等相关工作。我们以使用频率相对较高的ArrayList和HashMap为例,简要说明初始化的相关工作,并解释为什么在任何情况下,都需要显示地为集合容器设定初始化大小。
ArrayList
是存储同一类元素、存储顺序与存放顺序一样的集合,可重复,底层采用数组实现的集合。HashMap
是存储K-V键值对的哈希式结构集合。
ArrayList
先看其源码,java.util.ArrayList
案例
现在需要将1000个数据存储到一个ArrayList
中,采用默认构造函数,则需要13次扩容才可以完成这1000数据的存储,相反,如果在初始化的时候直接给ArrayList
初始化大小为1000的容量,一次性搞定。从而避免被动扩容和数组复制的额外开销。如果数据更大或超大,却没有注意初始容量分配的问题,那么无形中会给系统的性能损坏造成非常大的影响,搞不好还有可能OOM(Out Of Memory)
。
10-->15---→22---→33--→49--→74--→111--→166--→249--→373--→559--→838--→1000+
HashMap
为了提高运算速度,设定HashMap容量打下欧威2的n次方,这样的方式使计算落槽为止更快。threshold是以2的倍数增加,那么上面的例子存1000个数据到HashMap中则需要一下7次;HashMap扩容还是有不小的成本的,如果提前能够预估出HashMap内要存放的元素个数,就可以在初始化时设置合理容量大小,避免了不断扩容带来的性能损耗。
16-->32-->64-->128-->256-->512-->1000+
总结
综上所述,集合初始化时,指定集合初始容量大小。如果暂时无法确定集合大小的时候,才使用默认值,所以当你在使用集合的时候,请考虑考虑初始容量的大小,能记住各种集合初始大小是最好,如果实在是记不得,请在使用的时候看一下源码,因为源码中都有其初始化大小。ArrayList
默认大小为10,HashMap
默认大小为16。
