equals()
方法。我的回应是,你也重写了hashCode()
方法吗?他的回答是因为我们不会使用哈希映射或哈希集合,所以重写hashCode()
方法并不重要。这个回答正确吗?考虑到大多数IDE都提供了自动生成equals/hashcode功能,我认为没有太多理由不同时创建两者。
另一种看待它的方式是:当您覆盖父类的方法时,应遵循该父类定义的契约。在Object的情况下,javadoc of equals非常清楚:
请注意,通常必须重写hashCode方法,无论何时重写此方法,以维护hashCode方法的一般契约,该契约规定相等的对象必须具有相等的哈希码。
因此,除非您真正有设计理由不重写hashcode,否则默认决策应遵循父类契约并同时覆盖或不覆盖两者。
这是一个代码的坏味道。例如,Findbugs将在您覆盖hashCode或equals而未覆盖另一个时发出警告。您应该同时覆盖它们,以使它们相互一致(即,a.equals(b) => a.hashCode() == b.hashCode())。
现在稍加努力可能会在以后节省很多麻烦。
hashCode()
抛出异常)。我知道有些代码使用hashCode()
测试是否为空(即期望NPE)[虚假的getClass()
可能会更好] - 所以再次提议将其设置为默认选择有点冒险。 - bestsss每个覆盖equals方法的类都必须重写hashCode方法。否则,将违反Object.hashCode的通用契约,这将导致您的类无法与所有基于哈希的集合(包括HashMap、HashSet和Hashtable)正常配合使用。
《Effective Java》第9条:覆盖equals时总要覆盖hashCode。
如果您的类是公共类,则无法控制未来开发中如何使用您的类。除非查看源代码(或通过反射),否则没有办法知道此类是否已重写hasCode方法,如果用户在任何基于哈希的集合中使用它,他们将会受到结果的惊吓。
一般:
只覆盖那些你想以自己的方式使用的方法,以及那些受此覆盖影响的方法。
针对您的问题:
从Java文档中可以看到:
请注意,通常需要重写hashCode方法,每当equals()方法被重写时,以维护hashCode方法的一般契约,该契约规定相等的对象必须具有相等的哈希码。
假设您创建了两个不覆盖equals和hashCode方法的不同对象。然后,如果您调用equals方法,Java会隐式地调用hashCode方法,然后检查哈希码的相等性。
覆盖hashCode方法就足以检查两个对象的相等性。这对未来很有用。您可以在集合中使用此类。
否则,如果您只实现了equal方法,它只能解决两个对象的相等性问题,而不能更多。
equals
时不会隐式调用hashCode
。它使用==
来验证两个对象是否指向同一引用。即使你让hashCode
在每次调用时返回一个随机值,只要你指向同一个对象,equals
的默认实现仍然可以正常工作。 - Marc Baumbach
return 1;
——至少在技术上是正确的。 - Marko Topolnikreturn 1;
的问题在于,如果你之后使用了HashSet
,它很可能会导致难以调试的性能问题。相反,我会将hashCode()
实现为throw new UnsupportedOperationException()
,这只需要最少的工作量,但是当你回来并且之后使用HashSet
时,很明显你第一次没有费心实现hashCode()
。 - Louis WassermanhashCode
和equals
。IDE根本不知道如何高效地生成它们。我的观点是:如果想将一个类用作键,它必须像这样设计,包括不可变性。可变性不会影响将对象放入列表中,但会完全破坏它被包含在映射(集合)中。我宁愿有错误的hashCode,这样可以立即捕获它,而不是一个技术上正确的hashCode,一旦进入生产就有可能破坏性能。 - bestsss