我有两个类似的类,每个类别具有相同类型的单个字段。
class Fruit {
private final String name;
}
class Vegetable {
private final String name;
}
我想为每个实现hashCode()
。我的问题是,就我而言,名称之间的碰撞比" Apple"one_answers"胡萝卜"更有可能,并且它们都可能在同一地图/集合中。我想知道实施哈希码处理此问题的最清晰方法是什么。
到目前为止,我已经考虑了Objects.hash(this.getClass(), name)
,Objects.hash(<some int unique to this class>, name)
。我喜欢第一个,只是因为它比第二个更具自我记录和鲁棒性,但这并不是我在野外看到的模式。我也考虑了<some prime int unique to this class> * Objects.hashCode(name)
,但这感觉很脆弱,尤其是在添加新字段的情况下。
假设两个类扩展了一个共同的父级,我通过添加第二个字段来解决两个不同类别的实例,从而解决了这一点。这可能被认为是使用大卫·埃尔曼(David Ehrmann)在他的问题中建议的班级名称的另一种方式。但是,就我而言,使用其他字段看起来比使用类名称更合适。因此,这是我的抽象父班:
public abstract class NationalDish {
public String dishName;
public String country;
@Override
public int hashCode() {
return Objects.hash(country, dishName);
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof NationalDish)) {
return false;
}
NationalDish other = (NationalDish) obj;
return Objects.equals(dishName, other.dishName)
&& Objects.equals(country, other.country);
}
}
请注意,在父类中,在同一类中允许在同一类中定义Equals()和Hash Code()并将子类保持在最低限度:
public class EnglishDish extends NationalDish {
public EnglishDish(String dishName) {
this.dishName = dishName;
this.country = "England";
}
}
public class AmericanDish extends NationalDish {
public AmericanDish(String dishName) {
this.dishName = dishName;
this.country = "USA";
}
}
现在,使用国家名称(或问题中的植物类型),我们可以拥有相同的名称实例,看起来与Java不同:
public static void main(String[] args) {
NationalDish englishChips = new EnglishDish("Chips");
NationalDish americanChips = new AmericanDish("Chips");
System.out.println(englishChips.equals(americanChips)); // false
}