【问题标题】:Theoretical limit for number of keys (objects) that can be stored in a HashMap?可以存储在 HashMap 中的键(对象)数量的理论限制?
【发布时间】:2011-05-06 15:24:57
【问题描述】:

对于可以存储在 HashMap 中的键条目的数量是否有理论上的限制,或者最大值是否完全取决于可用的堆内存?

另外,哪种数据结构最适合存储大量对象(比如几十万个对象)?

【问题讨论】:

  • 您是要询问唯一键的数量还是条目数?我可以发誓 HashMap 是用桶构建的,所以虽然最多有 Integer.MAX_VALUE 个桶,但每个桶都可以有一个包含许多条目的列表。
  • 有趣的问题,得到我的 +1
  • 不同的人对大有不同的想法。你能更具体一点,你的意思是100、1000、数百万、数百万、数万亿吗?
  • 是的,我已经指定了大小(几十万或几百万)
  • 最喜欢的问题有我的 +1

标签: java performance hashmap


【解决方案1】:

HashMap 将值保存在一个数组中,该数组最多可以保存Integer.MAX_VALUE。但这不包括碰撞。每个Entry 都有一个next 字段,这也是一个条目。这就是解决冲突(具有相同哈希码的两个或多个对象)的方式。所以我不会说有任何限制(除了可用内存)

请注意,如果您超过 Integer.MAX_VALUE,您将在某些方法(如 size())中得到意外行为,但 get()put() 仍然有效。它们会起作用,因为任何对象的hashCode() 都将返回int,因此根据定义,每个对象都将适合地图。然后每个对象都会与现有对象发生碰撞。

【讨论】:

  • HashMap#size() 的文档实际上将键值映射的数量限制为一个 int 可以表示的数字。如果 HashMap 允许更多映射,则 size() 方法的文档将继承自 Map#size(),它定义了在大小 > Integer.MAX_VALUE 时返回 Integer.MAX_VALUE 的方法。
  • hashCode() 返回int。因此,桌子满了之后,只会有碰撞。
【解决方案2】:

对于可以存储在 HashMap 中的键条目的数量是否有理论上的限制,还是完全取决于可用的堆内存?

看看the documentation of that class,我会说理论极限是Integer.MAX_VALUE (231-1 = 2147483647) 个元素。

这是因为要正确实现此类,size() 方法必须返回一个 int,表示键/值对的数量。

来自HashMap.size()的文档

返回:此映射中键值映射的数量

注意:这个问题与How many data a list can hold at the maximum非常相似。


哪种数据结构最适合存储大量对象(比如几十万个对象)?

我会说这取决于您需要存储什么以及您需要什么类型的访问权限。所有内置集合可能都针对大批量进行了优化。

【讨论】:

  • 我刚刚注意到 size():int 方法:)
  • 其实size()并不是真正的问题:如果地图包含多个Integer.MAX_VALUE元素,则返回Integer.MAX_VALUE - download.oracle.com/javase/6/docs/api/java/util/Map.html#size()只有客户端代码没有识别size()的真正含义应该是个问题。
  • @gustafc,啊,有趣的一点。但是,HashMap.size() 的文档完善了该规范:download.oracle.com/javase/6/docs/api/java/util/… 不过,这是否可能是规范中的“错误”值得怀疑 :-)
  • @aioobe - 好吧,看看HashMap 的Sunoracle 实现,size 字段可能会溢出似乎并没有真正令人惊讶。规范合规性? :) 所以也许我应该说“size() 不应该真的不是问题”...
  • @jarnbjo,我不完全相信这不会被修复 - 我们也可以争辩说可能有代码依赖于 HashMap 正确实现 Map。当我或 aioobe 的错误报告得到回复时,我们会看看谁是对的。
【解决方案3】:

我同意@Bozho 的观点,并补充说您应该仔细阅读HashMap 上的Javadoc。请注意它如何讨论初始容量和负载因子以及它们将如何影响 HashMap 的性能。

HashMap 非常适合保存大量数据(只要您没有用完键或内存),但性能可能是个问题。

如果您发现无法在单个 Java/JVM 程序中操作所需的数据集,则可能需要查看分布式缓存/数据网格。

【讨论】:

    【解决方案4】:

    理论上没有限制,但是存储不同入口链的桶有一个限制(存储在不同的hashkey下)。一旦达到这个限制,每次新添加都会导致哈希冲突——但这不是问题,除了性能......

    【讨论】:

      猜你喜欢
      • 2015-05-29
      • 2012-08-30
      • 2023-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多