equals of case class with non-primitives 对于两个逻辑上相等的实例不能正常工作
equals of case class with non-primitives is not working correctly for two logically equal instances
对于两个逻辑上相等的 case class 实例,Equals 无法正常工作。
请在下面找到简化的案例 classes :-
case class Item(name : String)
case class Basket(items : Array[Item], bills : Map[Int, Int])
def createBasketInstance() : Basket = {
val maggi = Item("milk")
val coffee = Item("coffee")
val bills1 = Map(1 -> 20, 2 -> 75)
Basket( Array(maggi, coffee), bills1 )
}
val basket1 = createBasketInstance()
val basket2 = createBasketInstance()
basket1.equals(basket2) 的预期结果为真,但实际打印为假。
scalafiddle link : https://scalafiddle.io/sf/iJRKnMk/0
请找到附加的屏幕截图,以确认使用 scalatest 进行相等比较。
这与 case classes
的默认 equals
无关,而与 Arrays
的默认 equals
无关(这是您应该使用 Lists
的数百万个原因之一超过 Arrays
顺便说一句)
在 Scala 中,数组只是普通的 Java 数组,Java 中的数组被特殊对待(因为 JVM)
即使是简单的
Array(1, 2, 3) == Array(1, 2, 3)
将 return 错误。
为什么?因为数组继承 equals
方法的 Object.equals
只比较了 数组引用 而不是它们的内容。
我知道这听起来并没有那么糟糕,但我相信它会变得更糟。
您可能认为只需将数组分配给一个值就可以解决问题,对吗?好吧,事实并非如此。以下也会失败...
def createBasketInstance() : Basket = {
val maggi = Item("milk")
val coffee = Item("coffee")
val arr = Array(maggi, coffee)
val bills1 = Map(1 -> 20, 2 -> 75)
Basket( arr, bills1 )
}
因为这个函数的不同调用的调用栈不能共享引用,所以即使底层内容相同,每个函数调用都会创建一个新的引用。
你是怎么解决这个问题的?
java.utils.Arrays
中有一个名为 Arrays.equals
的方法可以进行深度比较。您可以 override
并构造它,以便比较使用 Arrays.equals
。您可能还需要覆盖 hashCode
写一个从 Array
到字面上任何其他集合
的隐式转换
首先不要使用数组。
我会说 #3 是解决此问题的方法
对于两个逻辑上相等的 case class 实例,Equals 无法正常工作。 请在下面找到简化的案例 classes :-
case class Item(name : String)
case class Basket(items : Array[Item], bills : Map[Int, Int])
def createBasketInstance() : Basket = {
val maggi = Item("milk")
val coffee = Item("coffee")
val bills1 = Map(1 -> 20, 2 -> 75)
Basket( Array(maggi, coffee), bills1 )
}
val basket1 = createBasketInstance()
val basket2 = createBasketInstance()
basket1.equals(basket2) 的预期结果为真,但实际打印为假。
scalafiddle link : https://scalafiddle.io/sf/iJRKnMk/0
请找到附加的屏幕截图,以确认使用 scalatest 进行相等比较。
这与 case classes
的默认 equals
无关,而与 Arrays
的默认 equals
无关(这是您应该使用 Lists
的数百万个原因之一超过 Arrays
顺便说一句)
在 Scala 中,数组只是普通的 Java 数组,Java 中的数组被特殊对待(因为 JVM)
即使是简单的
Array(1, 2, 3) == Array(1, 2, 3)
将 return 错误。
为什么?因为数组继承 equals
方法的 Object.equals
只比较了 数组引用 而不是它们的内容。
我知道这听起来并没有那么糟糕,但我相信它会变得更糟。
您可能认为只需将数组分配给一个值就可以解决问题,对吗?好吧,事实并非如此。以下也会失败...
def createBasketInstance() : Basket = {
val maggi = Item("milk")
val coffee = Item("coffee")
val arr = Array(maggi, coffee)
val bills1 = Map(1 -> 20, 2 -> 75)
Basket( arr, bills1 )
}
因为这个函数的不同调用的调用栈不能共享引用,所以即使底层内容相同,每个函数调用都会创建一个新的引用。
你是怎么解决这个问题的?
java.utils.Arrays
中有一个名为Arrays.equals
的方法可以进行深度比较。您可以override
并构造它,以便比较使用Arrays.equals
。您可能还需要覆盖hashCode
写一个从
的隐式转换Array
到字面上任何其他集合首先不要使用数组。
我会说 #3 是解决此问题的方法