2014-11-06 53 views
1

我想知道为什么new Integer(i).hashCode()new Long(i).hashCode()返回i但当hashCode()被某个其他对象如new Double(345).hashCode()调用时,它返回一个随机数。为什么?为什么新的Integer(i).hashCode()返回i?

+2

阅读关于'hashCode':http://en.wikipedia.org/wiki/Java_hashCode() – Crozin 2014-11-06 14:13:27

+0

它不会以'Long'的方式工作。尝试用'i = 2147483648l' – blgt 2014-11-06 14:23:05

+0

如果你阅读这些方法的源代码,它应该很明显,他们为什么不能相同。 – 2014-11-06 14:40:32

回答

8

因为一个Integer完全满足并与Object.hashCode()一般合同完全符合的int值:

hashCode的一般合同是:

  • 当在Java应用程序的执行过程中,它不止一次会在同一个对象上被调用,如果修改了对象的equals比较中没有使用的信息,hashCode方法必须始终返回相同的整数。该整数不需要从应用程序的一次执行到同一应用程序的另一次执行保持一致。

  • 如果两个对象根据equals(Object)方法相等,则对两个对象中的每个对象调用hashCode方法必须产生相同的整数结果。

  • 根据equals(java.lang.Object)方法,如果两个对象不相等,则不要求对这两个对象中的每一个调用hashCode方法都必须产生不同的整数结果。但是,程序员应该意识到,为不相等的对象生成不同的整数结果可能会提高散列表的性能。

简而言之:

的散列码为2个对象必须是如果equals()返回true是不同的相同的(但不是必需的),如果equals()返回false。同样通过Object.hashCode()声明它必须是int。理想情况下,散列码应该取决于散列的所有数据。的Long

Long

哈希代码必须映射的8个字节为4个字节(一个int的大小)。如果它符合的Long.hashCode()当前实现将只返回iint,不然它会与上部32位(4个字节)被异或运算:

return (int)(value^(value >>> 32)); 

散列码的Double

显然Doubledouble值不符合此条件。 Double也必须映射8个字节到4个字节。

Double.hashCode()会返回一个看似随机值,因为浮点数(floatdouble)没有存储“很好”,在保留给他们,但字节(如intlong例如,2的补码)使用IEEE 754 binary floating point standard等映射那些8字节到4(这正是实现所做的)将不会是一个有意义的数字,因为它使用2的补码表示形式。

long bits = doubleToLongBits(value); 
return (int)(bits^(bits >>> 32)); 
7

整数的值是一个足够好的散列,因为它与唯一整数本身一样唯一。

double必须以某种不同的方式散列,因为这里的散列必须是整数。

+0

所以散列总是必须是整数? – mac07 2014-11-06 14:21:25

+0

@ mac07是的,散列码必须是整数。 – Rohan 2014-11-06 14:23:28

3

becase的的implementation说:

Returns a hash code for this Integer. 

Returns:a hash code value for this object, equal to the primitive int value represented by this Integer object. 

707 
708  public int hashCode() { 
709   return value; 
710  } 
+0

@Downvote:为什么downvote?请解释。 – Jens 2014-11-06 14:15:45

1

Java中的不同类型计算散列码的方式不同,它们都是随机的。在长整型和Double的情况下,哈希码是值除了在那里它被转换为int

1

这是双重的情况下,因为Integer类返回值作为散列码的hashcode()方法。

Returns a hash code for this <code>Integer</code>. 

@return a hash code value for this object, equal to the 
      primitive <code>int</code> value represented by this 
      <code>Integer</code> object. 

public int hashCode() { 
return value; 
} 

虽然Double类的hashcode()方法执行一些操作并返回哈希码。

Returns a hash code for this Double object. The result is the exclusive OR 
    of the two halves of the long integer bit representation, exactly as produced by 
    the method {@link #doubleToLongBits(double)}, of the primitive double value 
    represented by this Double object. That is, the hash code is the value of the 
    expression: 

     public int hashCode() { 
     long bits = doubleToLongBits(value); 
     return (int)(bits^(bits >>> 32)); 
     } 
1

Integer类“盒子”一个原始int值,但它有自己的一个对象引用。如果Object.equals()指出两个相同的对象AB都必须表现出相同的Object.hashCode(),那么这样的哈希码是前者的int值是合理的。

至于Double,它的值可能会在系统之间改变,这就是为什么依靠不同的机制来提供散列码是有意义的。

相关问题