约书亚·布洛赫对有效的Java说:
必须在重写等于()的每个类中重写hashCode()。如果不这样做,将违反Object.hashCode()的一般约定,这将阻止类与所有基于散列的集合(包括HashMap、HashSet和Hashtable )一起正常工作。
我的重写equals()方法实现了比较Match对象的模糊评分算法:
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.
}这样,这些对象是相等的:
Match match0 = new Match("Man.City", "Atl.Madryt");
Match match1 = new Match("Manchester City", "Atlético Madryt");我应该如何重写hashCode()方法来为这样的对象生成相同的值?
发布于 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
发布于 2017-10-16 10:03:24
我建议您使用其他一些方法名,比如fuzzyEquals,而不是equals。您应该根据hashCode和equals的使用情况来查看它们。许多Java类(如HashMap )未经您的同意就调用了这两个方法,并要求它们严格遵守它们的想法。他们的想法不是你想要什么,而是他们需要什么。就像这样:
通过重命名,您可以(a)让HashMap和他的朋友高兴,(b)避免混淆,(c)提高可读性,(d)对于两种不同的事情有两种不同的方法,您可以独立使用或进一步组合。
发布于 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,如下所示。
// 16 bit for team 1 + 16 bit for team 2
0000000000000001 0000000000000010这是一个有效的32位整数,它将与match1 == match2和match1.hashCode() == match2.hashCode()的规则相匹配。
https://stackoverflow.com/questions/46766898
复制相似问题