Java正/负零和哈希表

时间:2017-03-13 16:07:56

标签: java double hashtable

javadocs状态

  

请注意,在大多数情况下,对于class Doubled1d2的两个实例,d1.equals(d2)的值为true当且仅当< / p>

    d1.doubleValue() == d2.doubleValue()
     

也具有值true。但是,有两个例外:

     
      
  • 如果d1d2都代表Double.NaN,则equals方法会返回true,即使Double.NaN==Double.NaN的值为false 1}}。
  •   
  • 如果d1代表+0.0d2代表-0.0,反之亦然,则等值测试的值为false,即使+0.0==-0.0 }具有值true
  •   
     

此定义允许哈希表正常运行。

为什么这两个例外必须“允许哈希表正常运行”?

等效地:哈希表如何不能使用Double的不同定义?

3 个答案:

答案 0 :(得分:4)

  

为什么这两个例外必须允许哈希表正常运行&#34;?

事实上,这种说法有点误导。更准确地说,Double.equals()的定义中的那些例外对于Double.hashCode()选择的实现与equals() 一致是必要的。该特性确实与Java平台库的哈希实现相关。你会在SO和其他地方找到大量专门针对该主题的措辞。例如:

由于涵盖了hashCode() / equals()一致性的一般主题,因此我将重点介绍它们如何应用于课程Double。这个领域有几个细节需要理解:

  • Java Doubledouble的包装类,double是根据IEEE-754二进制双精度格式定义的。
  • 在IEEE-754中,正负零是不同的值。尽管它们相互比较相同,但它们具有不同的位模式,并且它们可以通过它们的一些其他属性区分。出于某些目的,这是有用且可取的。
  • 另一方面,尽管IEEE-754定义了几个&#34;而不是数字&#34; (NaN)位模式,Java只使用其中一种。
  • IEEE-754指定其特殊的NaN值与每个值(包括它们自身)不相等。这是他们的一个显着特点。
  • Double.hashCode()是根据包裹double的位模式的算术运算定义的。

因为Double.hashCode()是根据包裹的double位模式计算的,并且正零和负零的位模式不同,所以哈希码为Double(+0.0)和{{ 1}}不同。如果两个此类Double(-0.0)实例比较相等,那么这会使hashCode()实现与equals()不一致。因此,Double被定义为比较相等。 这不是唯一的选择 Double.equals()可以改为定义,以便零的两种口味具有相同的哈希码。

另一方面,因为Java只提供一个类型为hashCode()的NaN值,并且具有特定的位模式,所以表示该值的double个实例产生相同的哈希码。虽然这是从Double的所选实现中得出的结果,但是在类hashCode()中镜像IEEE-754等式语义并不容易,因为这样做需要违反比{更重要的不变量Double。 {1}}与equals()保持一致:等于反身。也就是说,对于任何非空引用都hashCode()a为真,预计总是如此。

答案 1 :(得分:2)

第一个要点是满足equals和hash代码的合同(这是HashTable / HashMap使用的)。具体而言,根据equals Javadoc

,任何对象都必须等于自身
  

equals方法在非null对象引用上实现等价关系:

     
      
  • reflexive :对于任何非空参考值xx.equals(x)应返回true
  •   

由于哈希码为required to be consistent且具有equals方法的行为,因此这也适用于hashCode

  

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

因此,至少相同的NaN Double对象必须等于它自己。从技术上讲,不需要具有NaN值的Double的不同实例必须彼此相等。我的猜测是他们使所有NaN值相等,因为如果不是这样会让人感到困惑,并且与Double基本上是值类型的事实不一致,所以身份相等是不合适的。

但是我想不出为什么第二个例外是允许哈希表正常运行所必需的原因。

答案 2 :(得分:1)

这些例外是必要的,因为Double作为关键字的操作与其在计算中的操作不同。正负零的位模式不同,因此对于关键目的,它们不能相等,至少不容易。 NaN的位模式只是一种模式,因此出于关键目的,它不能不等于它自己。