【问题标题】:Most efficient key object type in a hash map?哈希图中最有效的键对象类型?
【发布时间】:2013-04-16 06:15:18
【问题描述】:

当使用HashMap 时,在速度方面,对象类型对元素检索有多大影响?假设我使用循环遍历大型哈希映射的可能键。我可以使用的最有效的密钥类型是什么?

到目前为止,由于简单起见,我使用字符串作为键对象类型。在编码时,这个问题突然出现在我的脑海中,引起了我的好奇心。我试图在网上搜索这个问题,但找不到我想要的答案。谢谢!

【问题讨论】:

  • 我不认为 oject 类型的关键在 HashMap 中的速度很重要。大小与对象类型无关。
  • 真的吗?当您考虑它时,它似乎很重要。必须进行一些比较,检查请求的键是否存在于哈希映射中。它可能会寻找内存位置,还是以不同的方式工作?现在我很想知道。不过,我相信你 XD 的解释会很棒。

标签: java object data-structures hashmap key


【解决方案1】:
  1. hashCode()equals() 应该很快

  2. hashCode() 应该分布良好,以尽量减少哈希冲突

【讨论】:

  • 2:请注意,java.util.HashMap 的实现使用了一些位混洗来确保键均匀分布,即使您的哈希码不是那么好。不过,您仍然必须确保它们是不同的。另请参阅此帖子:stackoverflow.com/questions/2414117/…
【解决方案2】:

您是尝试通过 get 方法还是通过迭代从 HashMap 中检索值?关于get方法,上面的人都回答过了。

如果您通过 entrySet 方法对 HashMap 进行迭代,则 HashMap 中键的类型无关紧要。此外,在每次迭代中都有一个 entrySet 条目,查找值变得毫无用处。另请注意,entrySet 通常优于 values 方法和 keySet 方法,因为它们都在内部使用 entrySet 迭代器并返回条目的键或值。

【讨论】:

    【解决方案3】:

    在您的情况下,重要的是元素的 hashCode 方法和 equals 方法的速度。使用Integers 很好,因为它们不需要对哈希值进行任何特殊计算。字符串也可以,因为哈希值在内部缓存,尽管使用equals 时它们的执行速度较慢。

    【讨论】:

      【解决方案4】:

      重要的是 equalshashCode 方法的实现。请参阅以下内容:What issues should be considered when overriding equals and hashCode in Java?

      由于这些函数用于哈希运算,因此当您对集合进行操作时,它们的效率就会发挥作用。

      作为旁注,请记住参考链接中提出的观点:

      确保您放入的关键对象的 hashCode() 当对象在集合中时,集合永远不会改变。这 确保这一点的防弹方法是使您的密钥不可变,这 还有其他好处。

      【讨论】:

        【解决方案5】:

        哈希映射会向您的密钥询问hashCode()。如果生成哈希码所花费的时间不合理,则此类对象的插入和检索时间会很长。以java.net.URL 为例。它的 hashcode 方法执行 DNS 查找。这样的对象不会成为哈希映射的好键。

        对于哪个是最佳密钥没有通用答案,因为没有最佳密钥。用于哈希映射的最佳键是检索所需的键。只需确保密钥的hashCode() 快速并正确使用int 空间。

        【讨论】:

        • 我讨厌听起来像一个四岁的孩子,但为什么没有最好的钥匙?在对象类型无关紧要的较低级别发生了什么?
        • 效率受 hashCode 和 equals 的影响,如这里的一些答案所示。但是没有最佳密钥的关键是您可能有理由使用哈希数据结构。如果您已经有一个现有的类型,您需要使用它来快速访问您的数据,那么您将使用该类型作为您的密钥 :-)
        • 对象类型并不像它的hashCode() 重要。哈希映射采用 hashCode 并对其应用哈希函数。哈希函数将 hashCode 从int 空间减少到 0 -> N 之间的索引,其中 N 是用于存储对象的数组的大小。归根结底,重要的是hashCode impl。 @Kirby 已经解释了我想要表达的观点。
        • 正如所有答案所暗示的那样,密钥本身并未存储。调用键的 hashCode() 方法来检索一个 int 值。然后这个 int 值在内部用作键。如果两个键对象具有相同的 hashCode() 结果,则在内部采取进一步的步骤来消除冲突并消除键/值对的歧义。当然,Integers 的 hashCode() 方法并没有太多的计算开销。因此,可以说,整数最适合用作键。但是,您的程序的需要可能会覆盖使用整数作为键。这就是 hashCode 方法的用途!
        • @Mike Adler 我现在明白了。当两个对象具有相同的哈希码时,您解释类型的重要性的方式更有意义。谢谢!
        猜你喜欢
        • 1970-01-01
        • 2022-11-22
        • 2012-05-02
        • 1970-01-01
        • 2023-01-24
        • 2011-03-29
        • 2019-04-20
        • 1970-01-01
        • 2022-07-06
        相关资源
        最近更新 更多