深挖java容器扩容背后隐藏的秘密

小白白跑去鹅厂面试,面试官提出了一个问题: 容器空间爆满怎么去扩容,说一说内部是如何处理的?我们的小白白不假思索的回答道:容器满了就要倒出来!啊?容器是装水的瓶子?(更多内容关注微信公众号: 白白家族)


 

一:容器为什么要扩容

在处理新增元素时,如果容器已满,就要先分配一块更大的内存空间,其次将容器的数据复制进来,再释放之前的内存,最后插入新增的元素。


 

二:那些容器要扩容

   底层实现包含数组类的需要扩容:如ArrayList,HashMap
   底层实现包含链表类的则不需要扩容:如LinkedList


 

三:各容器扩容汇总

容器初始空间扩容倍数加载因子
ArrayList101.5
Vector102
HashSet1620.75
HashMap1620.75
PriorityQueue111.5

 

四:为何选用倍数扩容,而不采用增加固定大小值扩容

1,以成倍方式增长

假定有 n 个元素,倍增因子为 m;那么,第 i 次重新分配将会导致迁移m^(i) (也就是当前的容器大小)个旧空间中元素;因此,n 次迁移操作所花费的时间复制度为O(n);均摊下来每次push_back 操作的时间复杂度为常数级别;

 

2,一次增加固定值大小

假定有 n 个元素,每次增加k个;n 次 push_back 操作所花费的时间复杂度为O(n^2);均摊下来每次push_back 操作的时间复杂度为O(n);

总结:对比可以发现采用采用成倍方式扩容,可以保证常数的时间复杂度,而增加固定值容量的只能达到O(n)的时间复杂度;

以上分析的太复杂,这里给出形象解释:容器扩容为原来的2倍(假设N足够大),采用成倍增长,一次扩容即可(包括数据迁移到新空间),而固定值K增长扩容方案,因为N远远大于增长量K时,就会发生N/k次扩容,这里会产生多次就数据迁移过程,因此,可见使用成倍的方式扩容的好处。


 

五,为何不选用更大倍数扩容

    主要是考虑空间浪费问题,根据预判i经验,成倍增长倍数不能太大,倍数设置最好为(1,2)之间,目前较为广泛使用的扩容数有两种,以2倍或1.5倍。


 

六,综述
   总结一下,容器扩容时候会迁移元素,所以频繁的扩容是对性能有消耗的,所以设置合理的容量的出事大小可以在很大程度上提高性能。

(更多内容关注微信公众号: 白白家族)
   扫描二维码:
    

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值