如果我重写.equals(),是否需要覆盖.hashCode(),即使我不使用HashMap?
如果我选择永不将我的对象存储在集合中,是否需要重写哈希码或可以为我的对象使用相同的哈希码?性能好坏?如果我重写.equals(),是否需要覆盖.hashCode(),即使我不使用HashMap?
不,你应该提供哈希码。你永远不知道明天你可能需要使用它
任何时候你重写哈希码,你也需要重写equals。 Hashcode必须返回相同的值才能进行比较,其中equals表示返回true,否则hashmaps将无法正常工作。
是的。如果可以改进默认实现,则覆盖哈希码。
这并非绝对必要,但如果您决定稍后存储和排序对象,则最好这样做。
它不会花费太多精力为你,如果你总是重写这些方法,更何况现代的IDE提供给您的这个功能
是否绝对有必要吗? No.
这是最佳做法吗?是。
如果不在6个月内它会回来咬你吗?也许。
有史以来最好的回复。此评论也是垃圾邮件 –
如果A.equals(B)
,那么A.hashCode() == B.hashCode()
必须为真。
如果!A.equals(B)
虽然,A.hashCode() == B.hashCode()
仍然可以是真实的。
如果您在覆盖equals()
时未覆盖hashCode()
,则将某些东西放入某些集合中实际上会丢失这些对象(它们不会检索)。因此,要么正确覆盖hashCode()
,要么覆盖它为return 1
。这将满足约束条件并正确工作,但如果您开始将其中的许多内容放入基于散列的集合中,则性能会很差。
为了解决这一点:
它是好还是坏的表现?
无论你需要它还是你没有。如果你需要它,你没有选择。如果你不这样做,它永远不会被调用。
Equal objects must have equal hash codes;这是任何阶级的合同。
如果你感觉懒得实现体面hashCode
方法你仍然可以符合这个合同执行:
@Override public int hashCode() {
return 0;
}
它将基于散列的集合表现不佳,但至少会是正确的。
其他人提到的只是返回一个常数值。如果您遗忘并将其放入基于散列的集合中,这可能会导致性能稍后出现混乱。我会考虑抛出一个UnsupportedOperationException,以便如果你确实想在以后使用它,你会发现很快,所以你可以继续并做一个适当的实现。
如果您确定将来在任何基于散列的集合中永远不会使用该对象,则不需要重写散列代码。也没有任何性能影响。但是,将它们一起覆盖以便该方法暴露的合同得到遵守是一种很好的做法。 – Scorpion
为什么程序员在面临决策时首先遇到的问题是“它如何影响性能”? – delnan