【问题标题】:Overriding hashCode when using HashMap, HashSet etc?使用 HashMap、HashSet 等时覆盖 hashCode?
【发布时间】:2015-05-29 07:20:54
【问题描述】:

问题在标题中。我使用HashMap如下:

Map<Player, Partner> m = new HashMap<Player, Partner>();
//do some on m

PlayerPartner 都只是代表数据模型的 POJO

public class Player{

    private int id;

    private String name;
    //etc, GET, SET
}

public class Partner{

    private int id;

    private String name;
    //etc, GET, SET
}

我想说这些类的两个对象是等价的iff它们具有相同的id。那么,我应该写hashCode 类似

public int hashCode(){
    return id;
}

这是一种正确的方法吗?当我要使用 HashMap 或类似的东西时,为什么要使用它?

【问题讨论】:

  • 如果你在谈论等价,你应该覆盖 equals
  • @Leon 不完全是,我不明白为什么我应该在使用 HashMap 时覆盖 shashCode
  • 对于您的 DTO,您应该始终覆盖 hashcode、equals 和 toString

标签: java hashcode


【解决方案1】:

这样的hashCode 会起作用。您还必须以一致的方式覆盖equals

@Override
public boolean equals(Object other)
{
    if (!(other instanceof Player))
        return false;
    Player op = (Player) other;
    return id == op.id;
}

【讨论】:

  • 是的,我读过关于覆盖 hashCode 和 equals 方法的内容。但我不明白为什么我应该这样做。例如,为什么我在使用 HashMap 时必须覆盖 equals?如果我覆盖equals而不覆盖hashCode会发生什么?
  • @St.Antario hashCode 和 equals 都用于定位 HashMap 中的键。两个不同的key可能有相同的hashCode(即使没有,也可能映射到HashMap中的同一个bucket,因为bucket的数量远小于可能的hashcode的数量),所以使用equals确定它们是否实际上相等。
  • @St.Antario 如果覆盖 equals 而不是 hashCode,将使用 hashCode 的默认实现。因此,两个具有相同 id(您认为相等)的 Player 可能具有不同的 hashCode,因此它们可能被放置在 HashMap 中的不同存储桶中,这意味着 containsKey 可能会错误地返回 false 并且您可以将相同的在地图中键入两次。
  • @St.Antario equalshashCode 的正确实现是一本书的主题。使用这些方法来实现 Java Collections API 是另一本书。您应该独立阅读此内容。
【解决方案2】:

对象存储在哈希桶中,假设您有 100 个对象,如果 100 个对象中有 50 个返回哈希码值“123”,其余 50 个返回“124”,则它们存储在不同的两个桶中,从而减少所需的搜索时间.

虽然搜索的首要目的是找到对象所属的桶,一旦找到桶然后调用equls方法找到对象

基于哈希的集合将具有相同哈希码值的对象组合在一起,而不是将所有对象存储在一个地方(搜索很困难),每个这样的组都存储在一个称为哈希桶的地方

【讨论】:

    猜你喜欢
    • 2014-02-09
    • 1970-01-01
    • 2013-01-24
    • 2017-11-19
    • 2013-03-15
    • 2020-02-09
    • 1970-01-01
    • 2016-05-28
    • 2023-02-14
    相关资源
    最近更新 更多