约书亚·布洛赫(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的相等操作

09-10 07:14
查看更多