[英]why two primitive doubles with same value have two different identityHashCode?
I learned that all primitives with same value have same identityHashCode
so, I wanted get identityHashCode
of some primitives.so when I tried with 2 doubles with same value it was giving different identityHashCode
I did following: 我了解到,与相同值的元都有相同
identityHashCode
所以,我希望得到identityHashCode
一些primitives.so的,当我和2个双打这是给不同的值相同试图identityHashCode
我没有以下内容:
int xInt=5;
int yInt=5;
System.out.println(System.identityHashCode(xInt));//output:1867083167
System.out.println(System.identityHashCode(yInt));//output:1867083167
double double1=5;
double double2=5;
System.out.println(System.identityHashCode(double1));//output:1915910607
System.out.println(System.identityHashCode(double2));//output:1284720968
two ints with same value have same identityHashCode
but two doubles with same value have different identityHashCode
why is that? 两个具有相同值的int具有相同的
identityHashCode
但是两个具有相同值的双精度具有不同的identityHashCode
为什么会这样?
Your code is boxing the primitive values. 你的代码正在装箱原始值。 (The primitive values themselves don't have an identity hash code, as that's only a concept that's relevant for objects.) Your code is equivalent to this:
(原始值本身没有标识哈希码,因为这只是与对象相关的概念。)您的代码等同于:
int xInt=5;
int yInt=5;
Integer xInteger = xInt;
Integer yInteger = yInt;
System.out.println(System.identityHashCode(xInteger));
System.out.println(System.identityHashCode(yInteger));
double double1=5;
double double2=5;
Double boxedDouble1 = double1;
Double boxedDouble2 = double2;
System.out.println(System.identityHashCode(boxedDouble1));
System.out.println(System.identityHashCode(boxedDouble2));
Now if you compare the references themselves, you'll see that xInteger == yInteger
is true, but boxedDouble1 == boxedDouble2
is false... so identityHashCode
is representing that relationship accurately. 现在,如果您比较引用本身,您将看到
xInteger == yInteger
为true,但boxedDouble1 == boxedDouble2
为false ...因此identityHashCode
正确表示该关系。
The reason your boxed integer references refer to the same object is that boxed integral types within a particular range are cached : 您的盒装整数引用引用同一对象的原因是缓存特定范围内的盒装整数类型 :
If the value p being boxed is the result of evaluating a constant expression (§15.28) of type boolean, char, short, int, or long, and the result is true, false, a character in the range '\ ' to '\' inclusive, or an integer in the range -128 to 127 inclusive, then let a and b be the results of any two boxing conversions of p.
如果装箱的值p是评估boolean,char,short,int或long类型的常量表达式(第15.28节)的结果,结果为true,false,则为'\\ u0000'到''范围内的字符\\ u007f'包含,或-128到127(含)范围内的整数,然后让a和b为p的任意两次装箱转换的结果。 It is always the case that a == b.
a == b总是如此。
The range can actually be bigger in practice, and an implementation could cache boxed doubles as well, but I haven't seen that happen. 在实践中,范围实际上可能更大,并且实现也可以缓存盒装双打,但我还没有看到这种情况发生。
i learned that all primitives with same value have same identityHashCode
我了解到所有具有相同值的基元具有相同的identityHashCode
That can't be true, since primitives, by definition, are not objects, and thus don't have an identity hash code in the first place. 这不可能是真的,因为根据定义,原语不是对象,因此首先没有标识哈希码。
When you're calling System.identityHashCode()
, the argument is boxed to an Integer or a Double. 当您调用
System.identityHashCode()
,参数将被装箱为Integer或Double。
And Integer boxing uses a cache for the frequently used integers (from -128 to 127 by default). 并且整数装箱使用常用整数的缓存 (默认情况下从-128到127)。 That's not the case for Double boxing.
双拳并非如此。
Try it with a large int, and you'll get different results, too. 尝试使用大型int,你也会得到不同的结果。
There's a boxing issue at play here - you can't compare primitive datatypes with identityHashCode
as it uses Object
as its parameter. 这里有一个拳击问题 - 您无法将原始数据类型与
identityHashCode
进行比较,因为它使用Object
作为其参数。
Returns the same hash code for the given object as would be returned by the default method hashCode()
返回与默认方法hashCode()返回的给定对象相同的哈希码
But of course double
isn't the same as Double
. 但当然
double
与Double
。
i learned that all primitives with same value have same identityHashCode.
我了解到所有具有相同值的基元具有相同的identityHashCode。
There are at least two misconceptions there. 那里至少存在两种误解。 First, primitives don't have hash codes or identity hash codes at all .
首先, 原始数据没有哈希代码或标识哈希代码在所有 。 It is Objects that do, such as the wrapper objects obtained by autoboxing primitive values.
它是对象 ,例如通过自动装箱原始值获得的包装器对象。
Second, the overall idea is simply wrong, as your own experiment demonstrates. 其次,总体思路完全错误,正如您自己的实验所证明的那样。 If you provide a primitive as the argument to
System.identityHashCode()
then it is autoboxed into an instance of the appropriate wrapper class, and the identity hash code of the resulting object is returned. 如果您提供一个原语作为
System.identityHashCode()
的参数,那么它将被自动装箱到相应包装类的实例中,并返回结果对象的标识哈希码。 An object's identity hash code is uniquely characteristic of that object during its lifetime, and independent of its state. 对象的标识哈希码在其生命周期中是该对象的唯一特征,并且与其状态无关。 No two objects existing at the same time have the same identity hash code.
同时存在的两个对象不具有相同的标识哈希码。 What's more interesting, then, is not that you get different identity hash codes for the autoboxed
double
s, but that you get the same identity hash codes for autoboxed small integers. 那么,更有趣的是,你不是为自动装箱的
double
s获得不同的身份哈希码,而是为自动装箱的小整数获得相同的身份哈希码。
In fact, this shows that Java maintains a cache of Integer
objects for small integer values. 实际上,这表明Java为小整数值维护了
Integer
对象的缓存。 It uses these when autoboxing values in the range covered, and when handling explicit Integer.valueOf()
invocations for those values. 它在覆盖范围内的自动装箱值时以及处理这些值的显式
Integer.valueOf()
调用时使用这些值。 Thus, in your example, you get the same object each time you autobox the integer 5, and you see the same identity hash code. 因此,在您的示例中,每次自动装订整数5时都会获得相同的对象,并且您会看到相同的标识哈希码。 If you used a sufficiently large value then you would not see the same effect.
如果您使用了足够大的值,那么您将看不到相同的效果。
Java does not perform such caching for the Double
s with value 5.0. Java不会为值为5.0的
Double
s执行此类缓存。
On the other hand, perhaps you simply misunderstood the lesson. 另一方面,也许你只是误解了这一课。 Distinct wrapper objects representing the same primitive type and value don't have the same identity hash code, but they do have the same (regular) hash code, because that, for the wrapper classes, is determined by the primitive values they represent.
表示相同的基本类型和值不同的包装对象不具有相同身份的散列码,但它们确实具有相同的(常规)散列码,因为,对于包装类,由它们所表示的原始值来确定。 So compare the results of your code to the results of this:
因此,将代码的结果与此结果进行比较:
System.out.println(Double.valueOf(double1).hashCode());
System.out.println(Double.valueOf(double2).hashCode());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.