我同意What issues should be considered when overriding equals and hashCode in Java?这篇文章中的陈述
使用用于计算equals()的同一组字段来计算hashCode()。
但我有些疑惑:
字段不必相同。要求是两个相等的对象,它们必须具有相同的哈希码。如果它们具有相同的哈希码,则它们不必相等。来自javadocs:
- 每当在执行Java应用程序期间多次在同一对象上调用它时,hashCode方法必须始终返回相同的整数,前提是不修改对象的equals比较中使用的信息。从应用程序的一次执行到同一应用程序的另一次执行,该整数不需要保持一致。
- 如果两个对象根据equals(Object)方法相等,则对两个对象中的每一个调用hashCode方法必须生成相同的整数结果。
- 如果两个对象根据equals(java.lang.Object)方法不相等,则不需要在两个对象中的每一个上调用hashCode方法必须生成不同的整数结果。但是,程序员应该知道为不等对象生成不同的整数结果可能会提高哈希表的性能。
例如,您可以始终返回1作为哈希代码,并且无论您在equals方法中使用哪个字段,都将遵守哈希代码协定。
一直返回1会改善hashCode的计算时间,但HashMap的性能会下降,因为它必须更频繁地使用equals()。
这是否必须具有相同的字段?
是的,如果你不想要任何惊喜。
如果是,如果我不使用相同的字段怎么办?
根据hashCode
方法,你可能得到相同的对象的equals()
不同,这是equals和hashCode契约的要求。
例如,假设你有3个字段 - a
,b
,c
。你使用a
和b
作为equals()
方法,并使用hashCode()
方法的所有3个字段。因此,对于2个对象,如果a
和b
等于,并且c
不同,则两者将等于具有不同的哈希码。
它会影响HashMap性能还是HashMap准确度?
这不是关于性能,而是你的地图不会按预期运行。
哈希码中使用的字段可以是equals中使用的字段的子集。它仍然遵守这条规则“每当a.equals(b),然后a.hashCode()必须与b.hashCode()相同”