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