【问题标题】:Overriding HashCode, when would not doing so be problematic? [duplicate]重写 HashCode,什么时候这样做不会有问题? [复制]
【发布时间】:2016-09-15 10:44:08
【问题描述】:

当覆盖对象的等号运算符来比较字段时,也有人说你应该覆盖hashCode()。

两个对象是否有相同的字段,但 hashCodes() 不同?为什么需要同时更新两者?

【问题讨论】:

    标签: java object hashcode equality


    【解决方案1】:

    覆盖两者的主要问题是许多容器假定这两种方法使用相同的策略。

    典型的情况是 HashMaps,如果你覆盖 equals()/hashCode() 之一但不是同时覆盖两者(或不一致地覆盖它们),它们可能不起作用,因为它们使用 hashCode() 来找到你的密钥应该的存储桶是,然后使用 equals() 在该存储桶内进行搜索。所以它最终可能会在错误的桶中搜索给定的键!顺便说一句,这就是为什么有时在 get() 时找不到键,但可以通过迭代每个元素来找到它:迭代不使用 hadhCode()。

    这与为什么你应该从不有一个在对象位于 HashSet/HashMap 中时更改其值的 hashCode() 类似的推理:当你搜索你的对象时,hashCode( ) 可能已更改并将您发送到不正确的存储桶。

    【讨论】:

      【解决方案2】:

      a.equals(b) 意味着map.put(a, c); map.get(b) 应该产生c,其中mapMapab 是键,c 是某个值。特别是,HashMap 可以非常快速地执行这些操作,但需要 a.hashCode()b.hashCode() 才能正确执行。如果a.hashCode() != b.hashCode() 那么它们将不会被识别为相等的键,并且使用HashMap 的程序将以非常令人沮丧和混乱的方式行为不端。您应该始终假设这是一种可能性,即使您目前不打算这样做。 不要实现一个没有另一个。这也不难做到:您的 IDE 可能会为您生成它(和equals)。 HashSet 等其他数据结构也使用它。

      【讨论】:

        猜你喜欢
        • 2012-10-19
        • 1970-01-01
        • 2013-10-19
        • 2011-07-20
        • 1970-01-01
        • 2014-03-13
        • 1970-01-01
        • 2020-06-17
        • 1970-01-01
        相关资源
        最近更新 更多