我想知道为什么new Integer(i).hashCode()
或new Long(i).hashCode()
返回i
但当hashCode()
被某个其他对象如new Double(345).hashCode()
调用时,它返回一个随机数。为什么?为什么新的Integer(i).hashCode()返回i?
回答
因为一个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()
当前实现将只返回i
成int
,不然它会与上部32位(4个字节)被异或运算:
return (int)(value^(value >>> 32));
散列码的Double
显然Double
的double
值不符合此条件。 Double
也必须映射8个字节到4个字节。
Double.hashCode()
会返回一个看似随机值,因为浮点数(float
和double
)没有存储“很好”,在保留给他们,但字节(如int
或long
例如,2的补码)使用IEEE 754 binary floating point standard等映射那些8字节到4(这正是实现所做的)将不会是一个有意义的数字,因为它使用2的补码表示形式。
long bits = doubleToLongBits(value);
return (int)(bits^(bits >>> 32));
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 }
@Downvote:为什么downvote?请解释。 – Jens 2014-11-06 14:15:45
Java中的不同类型计算散列码的方式不同,它们都是随机的。在长整型和Double的情况下,哈希码是值除了在那里它被转换为int
这是双重的情况下,因为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));
}
的Integer
类“盒子”一个原始int
值,但它有自己的一个对象引用。如果Object.equals()
指出两个相同的对象A
和B
都必须表现出相同的Object.hashCode()
,那么这样的哈希码是前者的int
值是合理的。
至于Double
,它的值可能会在系统之间改变,这就是为什么依靠不同的机制来提供散列码是有意义的。
- 1. 为什么对于(int i = 0; i <10; ++ i)和for(int i = 0; i <10; i ++)返回相同?
- 2. 为什么“for(i = 100; i <= 0; --i)”永远循环?
- 3. 为什么人们使用i = i + 1而不是i ++?
- 4. $ string [i]不返回第i个字符
- 5. var i返回undefined?
- 6. 为什么printf(“%d%d%d”,++ i,i,i ++)是未定义的行为?
- 7. 为什么mycourses [i] .getGrade()不返回任何东西(C++)?
- 8. 在JavaScript中,“i = + i”是什么意思?
- 9. out [i] = *(a_mat + i)在C中做什么?
- 10. i ++和++ i有什么区别?
- 11. SED -i +什么SOLARIS
- 12. 你为什么要用i =(i + 1)&mask来递增,mask是0b1111?
- 13. C++ STL - 为什么要用(W <* I),而不是(W == * I)
- 14. 为什么不编码:a [i] = i ++;工作?
- 15. I()的功能是什么?
- 16. 什么用的“声明-i”
- 17. Java的为什么对使用I,J
- 18. printf(“%d”,i ++)和i ++之间有什么区别;的printf( “%d”,i)的?
- 19. 为什么g ++不使用-I选项?
- 20. 为什么tab [i] [j] =“value”段落
- 21. Java For Loop,为什么J <I?
- 22. 在下面的JavaScript中,“function(i)”中的“i”是什么?
- 23. Delphi中的“i:= i - $ 24”这行代码中的“$”是什么?
- 24. 为什么函数中的childNodes [i]返回undefined,但是提醒一个对象?
- 25. Java - “(Customer)v.get(i)”做什么?
- 26. 什么是const TAB =^I pascal?
- 27. Django,最简单的forloop,怎么样? (i = 0; i <20; i ++)
- 28. document.forms [i] [j] .type的问题,返回undefined
- 29. 使用“for(i = 0; elem = array [i]; i ++)”来迭代数组有什么风险?
- 30. `times {| i |中的'i`变量是什么? ......'代表?
阅读关于'hashCode':http://en.wikipedia.org/wiki/Java_hashCode() – Crozin 2014-11-06 14:13:27
它不会以'Long'的方式工作。尝试用'i = 2147483648l' – blgt 2014-11-06 14:23:05
如果你阅读这些方法的源代码,它应该很明显,他们为什么不能相同。 – 2014-11-06 14:40:32