Является ли Scala BigDecimal нарушает контракт equals / hashCode? - PullRequest
3 голосов
/ 28 августа 2009

Как требует Ordered trait, метод equals в классе BigDecimal в Scala соответствует порядку. Тем не менее, хеш-код просто берется из переноса java.math.BigDecimal и, следовательно, несовместим с равно.

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 ]

7 голосов
/ 28 августа 2009

Люди из списка рассылки Scala User, похоже, согласны с тем, что это ошибка. Я думаю, что до сих пор его не взяли, потому что никто никогда не использовал BigDecimal в качестве ключа в хэш-структуре. Это было зарегистрировано как ошибка # 2304

0 голосов
/ 28 августа 2009

Обновление: Этот ответ неверный! Я оставил это, потому что я думаю, что комментарии полезны, чтобы видеть, почему это неправильно.


Это не пример нарушения договора equals / hashCode. Вам нужно проверить, равен ли d1.equals(d2), чтобы доказать это. И действительно, d1.equals(d2) возвращает ложь. Почему?

Это потому, что «2» - это не то же самое, что «2,00»; значение справа имеет более значимые цифры. Другими словами, они равны значению (2 == 2,00), но отличаются по шкале (0! = 2).

Если вы прочтете исходный код здесь , вы увидите, что для двух чисел он падает до реализации Java BigDecimal equals. Затем, читая документацию Java , вы узнаете, как это работает более подробно.

...