【问题标题】:Initial capacity for a HashSet<Integer>HashSet<Integer> 的初始容量
【发布时间】:2013-08-20 23:10:42
【问题描述】:

对于我知道要插入 1000 个整数以防止需要进行任何内部重建的 HashSet,我应该使用什么初始容量?

起初我认为我应该使用 1000,但阅读了构造函数的描述,该构造函数带有 initialCapacity 参数,它说Constructs a new, empty set; the backing HashMap instance has the specified initial capacity and default load factor (0.75).

所以如果我将容量设置为 1000,hashMap 将在达到 750 个元素时调整大小?

我还假设 hashMap 的有效性需要一些“空间”,因此解决 IC*0.75=1000 以获得类似 1334 的结果也可能不是最佳解决方案,或者是吗?

更新:
1) 我知道内部调整大小的意义并不重要,但它仍然是一个学习和更好地理解我正在使用的环境的机会。并且努力应该是最小的。

2) 关于数据结构选择的几个cmets。请在此处查看我之前的 Q:Data structure recommendation,其中提供了有关我的场景的更准确信息。

【问题讨论】:

  • 你要插入超过 1000 个整数吗?
  • 那你为什么不使用这个构造函数呢? HashSet(int initialCapacity, float loadFactor)
  • 那几纳秒对你来说一定很重要。
  • @KevinBowersox 我将准确插入 1000 个整数。
  • 如果您知道您将使用 1000 个整数并且您非常努力地避免重建,那么更具体的数据结构是否合适?

标签: java data-structures hashmap hashset


【解决方案1】:

您需要size/load-factor 以避免调整大小。注意:对于 HashSet 和 HashMap,它始终是 2 的下一个幂。

【讨论】:

  • 二的幂是多少?比例还是大小? (显然不是负载因素)。我也猜你答案中的 HashMap 应该是一个 HashSet ...
  • @epeleg 存储桶数量的容量始终是 2 的幂。因此使用位掩码代替模数来为哈希找到正确的存储桶。
【解决方案2】:

如果它真的值得担心(我怀疑它不是 - 调整一组 1000 个整数的大小不会花费很长时间),那么请记住 HashSet 由 @ 支持987654325@和put方法引用this

addEntry(int hash, K key, V value, int bucketIndex) {

   Entry<K,V> e = table[bucketIndex];

   table[bucketIndex] = new Entry<K,V>(hash, key, value, e);
   if (size++ >= threshold)
      resize(2 * table.length);
}

对于此类查询,checking out the source code 总是值得的,但请记住,实现可能总是会发生变化(即使对于 次要 JRE 版本)。

最后,这个场景是否适合?如果你有一个固定大小的整数分配,也许一个简单的数组(使用原语,从而避免装箱)会更快/更简单?

【讨论】:

  • 知道拒绝正确答案的原因总是很有趣。投反对票的人,请花一分钟时间解释你的理由!
  • 是的。我会同意的!
  • 感谢您对 grepCode 的引用 - 我不知道。我也同意反对票。但是我在展示这段特定的代码时错过了你的观点。至于数据结构的选择,请看我之前的Q:stackoverflow.com/questions/18299937/…因为它更好地解释了完整的场景。
【解决方案3】:

我认为,理想的初始容量是将其保持为您要插入的整数数量,并将负载因子保留为默认值。

选择 /0.75 负载因子。

【讨论】:

  • 这不能保证我至少在重建时有 100% 的把握吗?
【解决方案4】:

对于您的情况,将初始容量设置为 1000 并将负载因子设置为 1 是合理的,因为两个 不同 Integers 不会共享相同的哈希(即 int 本身) .

尽管如此,出于一般目的,您不应该真正关心负载系数并保持原样,因为您自己可能永远不会注意到任何改进。增加负载因子实际上可能会导致性能急剧下降。

【讨论】:

  • 如果一定要设置load factorinitial capacity我相信这是最好的答案。将容量设置为您需要的容量,并将负载系数设置为需要全套。由于您的设置大小是固定的,因此不应重新加载。
  • 整数本身如何成为哈希键?假设它们来自 0-999999 的范围?而 hashMap 只有 1000 个桶......我在这里遗漏了什么吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-30
相关资源
最近更新 更多