约书亚·布洛赫(Joshua Bloch)在有效Java上说:
您必须在每个覆盖equals()的类中覆盖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()
方法为此类对象生成相同的值? 最佳答案
正如M. le Rutte和AxelH的回答所言,equals应该只对相同的对象返回true(应该可以随时切换,并在代码中呈现相同的结果,而不管使用哪种方式)。
解决此问题的一种方法是使用包装类,如Remove duplicates from a list of objects based on property in Java 8的答案所述。
您可以使包装器类仅存储计算的模糊值,然后在equals和哈希码中进行比较并使用这些值,然后可以使用unwrapp来获取真实值。
另一种方法是像yshavit所说的那样做,并做另一个类似于String:equalsIgnoreCase的相等操作