Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 通过equals&;区分子类;哈希码_Java_Equals_Hashcode - Fatal编程技术网

Java 通过equals&;区分子类;哈希码

Java 通过equals&;区分子类;哈希码,java,equals,hashcode,Java,Equals,Hashcode,我正在寻找关于在子类中重写hashcode和equals的指导 我在这里发现了一个类似的问题: 但我想要的是稍微不同的东西 想象一下这个(有点愚蠢的)例子: 鉴于: 子类不添加任何额外字段 至少在本例中,它们基本上只是标记类 同名的水果和蔬菜不应相等 问题: 您是否希望子类equals只包含子类的instanceof检查和对super.equals的调用 为了使同名的水果和蔬菜实例具有不同的哈希代码,应该如何构造哈希代码 您可以在Foo的.equals()中使用.getClass(): 您希

我正在寻找关于在子类中重写hashcode和equals的指导

我在这里发现了一个类似的问题:

但我想要的是稍微不同的东西

想象一下这个(有点愚蠢的)例子:

鉴于:

  • 子类不添加任何额外字段
    • 至少在本例中,它们基本上只是标记类
  • 同名的
    水果
    蔬菜
    不应相等
  • 问题:

  • 您是否希望子类equals只包含子类的
    instanceof
    检查和对
    super.equals
    的调用
  • 为了使同名的
    水果
    蔬菜
    实例具有不同的哈希代码,应该如何构造哈希代码

  • 您可以在
    Foo
    .equals()中使用
    .getClass()

  • 您希望equals只包含一个instanceof check和一个对super.equals的调用吗
  • instanceof
    在这里是危险的,因为
    Food
    不是抽象的。这意味着
    equals
    不是对称的

    someFruit.equals(someFood) // will be false
    someFood.equals(someFruit) // will be true
    
    这可能不是一个问题,但这是你应该考虑的事情。

    如果你不想破坏合同,那么在这种情况下,
    食品
    应该检查
    this.getClass()==obj.getClass()
    。如果您这样做,那么您也不一定需要在子类中重写它

    否则就没关系了。该方法是按合同定义的,您可以根据需要实现它

  • 为了使具有相同名称的水果和蔬菜实例具有不同的哈希代码,应该如何构造哈希代码

  • 它们不需要不同。

    您可以使用类名作为hashcode的一个组件(例如:
    17*classname.hashcode()+super.hashcode()
    )注意,Java API中的许多数据结构都显示了您在这里显示的行为。看看各种各样的地图。例如,HashMap可以等于LinkedHashMap。地图会检查地图的内容。实现类其实并不重要。是的,看起来很公平,除了我试图表现得很好,并试图坚持Josh Bloch的想法“当你重写等于时总是重写hashCode”,你确实重写了hashCode。同样,没有要求如果
    !o1.equals(o2)
    then
    o1.hashCode()!=o2.hashCode()
    。或者你误解了“你不在乎”的部分。我的意思是“这没问题”:=)请注意,这是一个合法的hashCode()实现,尽管它非常无用:
    return42
    
    @Override
    public final boolean equals(final Object obj)
    {
        if (obj == null)
            return false;
        if (this == obj)
            return true;
        // Class<?> are signletons, therefore we can use ==/!=
        if (getClass() != obj.getClass())
            return false;
        return name.equals(((Foo) obj).name);
    }
    
    @Override
    public final int hashCode()
    {
        return 31 * getClass().hashCode() + name.hashCode();
    }
    
    someFruit.equals(someFood) // will be false
    someFood.equals(someFruit) // will be true