java - 如果hashCode没有被覆盖会怎么样?

时间:2013-01-30 16:19:52

标签: java hashcode

  

可能重复:
  what is an objects hashcode

假设我创建了一个名为Employee的对象,它具有id,firstName,lastName和电子邮件,用于实例变量和相应的setter / getter方法。如果hashCode()对象存储在集合对象中时不覆盖hashCode(),那么如何计算Employee

5 个答案:

答案 0 :(得分:23)

如果不覆盖hashcode(),则集合将使用Object类中的默认实现。此实现为不同的对象提供不同的值,即使它们根据equals()方法相等。

某些集合(如HashSet,HashMap或HashTable)使用哈希代码存储其数据并检索它。如果您没有以一致的方式实现hashcode()和equals(),那么它们将无法正常运行。

编辑:

根据Javadoc:Object.hashcode()通常是通过将对象的内部地址转换为整数来实现的,但Java(TM)编程语言不需要这种实现技术。 。因此,我建议不要依赖具体的实施。对于实现的实际操作,请参阅this answer类似的问题。

答案 1 :(得分:8)

来自文档:

  

尽可能合理实用,由hashCode方法定义   class Object确实为不同的对象返回不同的整数。 (这个   通常通过转换内部地址来实现   将对象转换为整数,但这种实现技术不是   JavaTM编程语言所要求的。)

所以基本上当你存储在Map / Set / somethingThatRequiresHashCode中时,JVM将使用该实例的内部内存地址来计算hashCode,保证(尽管散列函数保证任何东西 - 它们不保证)每个不同实例将具有唯一的hashCode。

由于关于equals和hashCode的Object契约,这一点特别重要,因为:

  

类Object的equals方法实现最具辨别力   对象可能的等价关系;也就是说,对于任何非null   引用值x和y,当且仅当x时,此方法返回true   和y引用相同的对象(x == y的值为true)。

如果不覆盖equals,它将比较两个引用的内部地址,它与hashCode背后的逻辑相匹配。

如果您的问题与以下内容更相关:JVM是否会查看实例中的值以确定相等/计算哈希码,答案是否定的,如果您这样做:

MyObject a = new MyObject("a", 123,"something");
MyObject b = new MyObject("a", 123,"something");

ab将使用不同的哈希码。

答案 2 :(得分:2)

来自有效的Java第二版

  

第9项:覆盖equals

时始终覆盖hashCode      

一个常见的   错误的来源是无法覆盖hashCode方法。您   必须覆盖覆盖等于的每个类中的hashCode。失败   这样做会导致违反一般合同   Object.hashCode,它将阻止您的类运行   正确地与所有基于散列的集合一起使用,包括   HashMap,HashSet和Hashtable。

我建议你阅读那一章。有很多例子,你可以学习,如果你不这样做会发生什么。

答案 3 :(得分:1)

它取决于集合,即使没有覆盖元素的hashCode,大多数集合也应该工作,除了HashSet之类的集合,它依赖于元素hashCode才能正常工作。 请注意,集合的hashCode通常依赖于元素的hashCode:

  

返回此集合的哈希码值。而收藏   界面没有对一般合同的规定   Object.hashCode方法,程序员应注意任何类   覆盖Object.equals方法也必须覆盖   Object.hashCode方法以满足一般合同   Object.hashCode方法。特别是,c1.equals(c2)意味着   c1.hashCode()== c2.hashCode()

请参阅:http://docs.oracle.com/javase/6/docs/api/java/util/Collection.html#hashCode%28%29

答案 4 :(得分:0)

**type of field**             **hash code formula**

boolean                       fieldHash = f ? 0 : 1

any integer type except long  fieldHash = (int) f

long                          fieldHash = (int) (f ^ (f >>> 32))

float                         fieldHash = Float.floatToIntBits( f )

double                        int v=Double.doubleToLongBits(f)

fieldHash                     (int) (v ^ (v >>> 32))

any Object reference          fieldHash = f.hashCode()

如果您编写自定义类型,则负责创建一个最佳表示当前实例状态的良好hashCode实现。

http://content.hccfl.edu/pollock/AJava/HashCode.htm