首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >重写hashCode()方法

重写hashCode()方法
EN

Stack Overflow用户
提问于 2017-10-16 09:22:08
回答 3查看 625关注 0票数 0

约书亚·布洛赫对有效的Java说:

必须在重写等于()的每个类中重写hashCode()。如果不这样做,将违反Object.hashCode()的一般约定,这将阻止类与所有基于散列的集合(包括HashMap、HashSet和Hashtable )一起正常工作。

我的重写equals()方法实现了比较Match对象的模糊评分算法:

代码语言:javascript
复制
public class Match {

    private String homeTeam;

    private String awayTeam;

    public Match(String homeTeam, String awayTeam) {
        this.homeTeam = formatTeamName(homeTeam);
        this.awayTeam = formatTeamName(awayTeam);
    }
}

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Match that = (Match) o;

        final int threshold = 6;

        return (computeFuzzyScore(this.homeTeam, that.awayTeam) <= threshold || computeFuzzyScore(this.awayTeam, that.homeTeam) <= threshold) &&
                    computeFuzzyScore(this.homeTeam, that.homeTeam) > threshold && computeFuzzyScore(this.awayTeam, that.awayTeam) > threshold;

    }

    // formatTeamName(), computeFuzzyScore() have been left out for brevity.
}

这样,这些对象是相等的:

代码语言:javascript
复制
Match match0 = new Match("Man.City", "Atl.Madryt");
Match match1 = new Match("Manchester City", "Atlético Madryt");

我应该如何重写hashCode()方法来为这样的对象生成相同的值?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-10-16 09:42:21

正如M. le Rutte和AxelH的回答已经说过的那样,等于应该只对相同的对象返回true (应该可以在任何时候切换并在代码中呈现相同的结果,不管使用的是哪种)。

解决这一问题的一种方法是使用包装器类,在Remove duplicates from a list of objects based on property in Java 8的答案中描述了这一点。这样包装器类只存储计算出来的模糊值,并比较和使用相等值和哈希代码中的值,然后可以使用unwrapp获取实际值。

另一种方法是像yshavit所说的那样做另一个类似于字符串的等号:equalsIgnoreCase

票数 2
EN

Stack Overflow用户

发布于 2017-10-16 10:03:24

我建议您使用其他一些方法名,比如fuzzyEquals,而不是equals。您应该根据hashCodeequals的使用情况来查看它们。许多Java类(如HashMap )未经您的同意就调用了这两个方法,并要求它们严格遵守它们的想法。他们的想法不是你想要什么,而是他们需要什么。就像这样:

  • 等于= homeTeam.equals && awayTeam.equals
  • hashCode = homeTeam.hashCode ^ awayTeam.hashCode

通过重命名,您可以(a)让HashMap和他的朋友高兴,(b)避免混淆,(c)提高可读性,(d)对于两种不同的事情有两种不同的方法,您可以独立使用或进一步组合。

票数 1
EN

Stack Overflow用户

发布于 2017-10-16 09:35:06

重要的是,如果match1 == match2那么match1.hashCode() == match2.hashCode()。假设您有一个数据库,您可以用一个id (一个数字)存储匹配,然后让hashCode返回id并完成。

如果不使用数据库来跟踪匹配的id,您就可以为每个团队分配一个固定长度的数字id,并将这两个id作为hashCode的结果连接起来。

例如,"Manchester City"团队可以是team 1"Atlético Madryt" team 2。如果散列长度为32位,则可以让前16位是team 1,最后16位是team 2,如下所示。

代码语言:javascript
复制
// 16 bit for team 1 + 16 bit for team 2
0000000000000001        0000000000000010

这是一个有效的32位整数,它将与match1 == match2match1.hashCode() == match2.hashCode()的规则相匹配。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46766898

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档