Scala的BigDecimal违反了equals / hashCode合约吗?

时间:2009-08-28 08:02:32

标签: scala equals hashcode bigdecimal

由于Ordered trait要求,Scala的equals类上的BigDecimal方法与排序一致。但是,哈希码只是从包装的java.math.BigDecimal中获取,因此与equals不一致。

object DecTest {
  def main(args: Array[String]) {
    val d1 = BigDecimal("2")
    val d2 = BigDecimal("2.00")
    println(d1 == d2) //prints true
    println(d1.hashCode == d2.hashCode) //prints false
  }
}

我找不到任何关于这是一个已知问题的提法。我错过了什么吗?

2 个答案:

答案 0 :(得分:7)

Scala用户邮件列表上的人们似乎同意这是一个错误。我想它直到现在才被发现,因为没有人曾使用BigDecimal作为哈希结构中的关键字。这是filed as bug #2304

答案 1 :(得分:0)

更新:这个答案错了​​!我把它留下了,因为我觉得这些评论很有用,可以看出它为什么是错误的。


这不是违反equals / hashCode合同的示例。您需要检查d1.equals(d2)是否等于证明这一点。实际上,d1.equals(d2)返回false。为什么呢?

这是因为“2”与“2.00”不完全相同;右边的值有更多有效数字。换句话说,它们在(2 == 2.00)中相等,但 scale (0!= 2)不同。

如果您阅读了源代码here,则可以看到对于两个数字,它将落实到Java BigDecimal equals实现。然后,阅读Java documentation将更详细地描述其工作原理。