Scala Contains()在列表和树集上执行不同的操作
我遇到了一个奇怪的情况,在Scala中,contains函数在列表和树集之间的工作方式似乎不同,我不知道为什么或者如何解决它 为了简洁起见,我创建了一个名为DataStructure的类。它包含两个元素:一个坐标对i,j和一个Int。它比这更复杂,但在这个MWE中,它看起来像是一个自定义比较器,它将按Int排序,我已经重写了hashCode和equals,因此包含相同坐标对i,j的两个元素被视为相等,而不管Int如何 当我将DataStructure的一个实例放入一个列表和一个树集合中时,程序在查找精确的匹配项时没有问题。但是,当检查具有相同坐标对但不同Int的新元素时,List.contains返回true,而TreeSet.contains返回false。为什么会发生这种情况?我如何解决 这是我的代码简化为最低限度的工作示例: 类数据结构 驱动程序Scala Contains()在列表和树集上执行不同的操作,scala,treeset,Scala,Treeset,我遇到了一个奇怪的情况,在Scala中,contains函数在列表和树集之间的工作方式似乎不同,我不知道为什么或者如何解决它 为了简洁起见,我创建了一个名为DataStructure的类。它包含两个元素:一个坐标对i,j和一个Int。它比这更复杂,但在这个MWE中,它看起来像是一个自定义比较器,它将按Int排序,我已经重写了hashCode和equals,因此包含相同坐标对i,j的两个元素被视为相等,而不管Int如何 当我将DataStructure的一个实例放入一个列表和一个树集合中时,程序在
package runtime
import foo.DataStructure
import scala.collection.mutable.TreeSet
object Main extends App {
val ts = TreeSet[DataStructure]()
val a = new DataStructure((2,2), 2)
val b = new DataStructure((2,3), 1)
ts.add(a)
ts.add(b)
val list = List(a, b)
val listRes = list.contains(a) // true
val listRes2 = list.contains(new DataStructure((2,2), 0)) // true
val tsRes = ts.contains(a) // true
val tsRes2 = ts.contains(new DataStructure((2,2), 0)) // FALSE!
println("list contains exact match: " + listRes)
println("list contains match on first element: " + listRes2)
println("TreeSet contains exact match: " + tsRes)
println("TreeSet contains match on first element: " + tsRes2)
}
输出:
list contains exact match: true
list contains match on first element: true
TreeSet contains exact match: true
TreeSet contains match on first element: false
几乎可以肯定,List.contains会检查每个元素是否相等以查找匹配项,而TreeSet.contains会遍历树并使用compare查找匹配项
你的问题是,你的比较与你的同龄人不一致。我不知道你为什么这么做,但不要:
Ordered[A]实例的equals方法必须与compare方法一致。几乎可以肯定,List.contains正在检查每个元素的equals以找到匹配项,而TreeSet.contains正在遍历树并使用compare来查找匹配项
你的问题是,你的比较与你的同龄人不一致。我不知道你为什么这么做,但不要:
Ordered[A]实例的equals方法必须与compare方法一致。即使在vanilla Java中,equals和compareTo之间的一致性也是可比契约的一部分,因为equals和hashCode之间的一致性是对象契约的一部分,因此,在这种情况下,3必须是一致的,即使在香草Java中,equals和compareTo之间的一致性也是可比契约的一部分,因为equals和hashCode之间的一致性是对象契约的一部分,所以在这种情况下,3必须是一致的,您已经有了答案,但是我想补充一点,使用hashcode作为equals是个坏主意,因为在不同的对象上可以有相等的hashcode。你已经有了答案,但是我想补充一点,使用hashcode作为equals是个坏主意,因为在不同的对象上可以有相等的hashcode。
list contains exact match: true
list contains match on first element: true
TreeSet contains exact match: true
TreeSet contains match on first element: false