在看不懂源码的情况下,事先知道集合需要放置多少元素时,如何设置最优的集合初始容量

20 篇文章 0 订阅

如果不想看源码,善用工具同样可以解决问题,

图中黄框圈中的多选框默认是勾选的,取消勾选后,debug模式下查看查看集合结构时就可以看到开辟的底层数组的大小了。

以 HashSet 举例,假设事先知道自始至终该集合一共需要添加 1 个元素,则可以用如下方式找到设置多大的初始容量是最优的:

1. 首先不设置初始容量:

发现执行完 "Set<String> names = new HashSet<String>()" 这句代码后,集合中的内部结构是这样的,红框中的部分表明此时还未分配数组空间。

发现执行完 "names.add( "zhangsan" )" 这句代码后,红框显示此时分配了一个长度为16的数组空间。

因为只需要增加一个元素,但是最终分配了16个长度的空间,感觉使用率非常低,不是我们想要的,于是我们尝试将初始容量设置为 1 看一下最终分配的数组空间长度是多少。

2. 初始容量设置为 1:

执行完 "Set<String> names = new HashSet<String>( 1 )" 这句代码后,分配数组空间如图红框显示。

执行完 "names.add( "zhangsan" )" 这句代码后发现分配的数组长度为 2,为什么不是 1 呢?因为有负载因子在“作怪”,因为设计者为了使得不是每次新增时都扩容,所以扩容策略也是费了一番功夫的,不是按需扩容( 按需扩容就是需要新增 1 个元素,就增加 1 个长度的空间,计算机世界里很多都不是 “按需”,因为 “按需”导致的效果很差 ,比如磁盘不是按需加载数据,而是按页加载 ),所以希望最终分配的最优长度是 1 是不可能的,而是 2( 这时候的使用率相对于初始容量不做任何设置时的使用率提高的已经相当可观了 ),初始容量设置为2,3,4...更没戏,因为基于扩容策略的存在,最终分配的数组空间长度将是只增不减。

 

 

假设事先知道整个过程中一共需要增加 100 个元素,则如何确定该设置最优的初始容量呢?

我们现在不知道最终会分配的空间数组长度是多少,但是知道一定大于等于100,如果不设置初始容量,当执行完第一个 add 之后,分配的空间长度会为 16,

后面肯定会进行多次扩容,导致最终分配的空间长度大于100,可以跑一下看一下,测试发现时 256,所以如果最开始就设置一个 256 的初始容量,则整个过程不会进行

任何扩容,节省了很多计算。 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值