Hashcode为不同的引用返回相同的值

时间:2016-01-29 13:57:04

标签: java

我在想哈希码只在HashMap,Hashtable中实现。在我的理解中,hashCode值对于对象级别也是相同的。 因此

        String str="Niks";
        String str1=new String("Niks");
        System.out.println(str.hashCode());
        System.out.println(str1.hashCode());

返回相同的代码,因为在对象级别,哈希码将如下实现。如果我错了,请纠正我。

 result = prime * result + ((str == null) ? 0 : str.hashCode()); 
 result2 = prime * result + ((str1 == null) ? 0 : str1.hashCode()); 

输出:

75268767 75268767

2 个答案:

答案 0 :(得分:2)

通常如果我在字符串中使用字符串作为键,我不想担心我用作查找键的字符串是否与我插入的字符串完全相同以前,这会使事情变得非常复杂。我希望能够创建一个字符串作为键,并且知道如果地图的字符串与我正在使用的字符串相同,那么地图就会找到它。所以比较参考不是我想要的,我想按价值进行比较。

对于像字符串或数字这样的对象(java.lang.Integer,java.math.BigInteger,java.math.BigDecimal),通常比较引用是没有用的;所有人都感兴趣的是价值。这些被称为值对象,而相等和hashCode严格基于对象的值,而不是基于比较引用。

来自definition posted by Martin Fowler

  

在EAA的P中,我将Value Object描述为一个小对象,例如Money或日期范围对象。它们的关键属性是它们遵循值语义而不是引用语义。

     

你通常可以告诉他们,因为他们的平等概念不是基于身份,而是如果他们的所有领域相等,则两个价值对象是相等的。虽然所有字段都相同,但如果子集是唯一的,则不需要比较所有字段 - 例如货币对象的货币代码足以测试相等性。

     

一般的启发式方法是值对象应该是完全不可变的。如果要更改值对象,则应使用新对象替换该对象,并且不允许更新值对象本身的值 - 可更新值对象会导致别名问题。

答案 1 :(得分:1)

当您将对象插入HashTable,HashMap或HashSet时,会使用hashCode()对象方法。同样重要的是equals()方法。

如果两个对象是equal,就像您在示例中演示的那样(两个字符串值为' Niks')(有关详细信息,请参阅this answer),那么他们将拥有同样的Hash,需要注意的一点是,仅仅因为两个对象具有相同的哈希值,它们可能不相等!