Java HashCode用于类似类



我有两个类似的类,每个类别具有相同类型的单个字段。

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
}

相关内容

  • 没有找到相关文章

最新更新