假设我有一个通用类Moo
,它没有实现contains
方法。如果我尝试将此类的5个实例添加到scala MutableSet
,它如何知道重复数据删除?
即,如果我创建一个Set(moo1, moo2, moo3, moo4, moo5)
Scala使用什么算法来删除重复项?
答案 0 :(得分:2)
如果你说Set(moo1, moo2, moo3, moo4, moo5)
,它会创建HashSet
个Moo
个对象。为了确定重复项,它通过调用其hashCode
函数来散列每个元素。在发生哈希冲突时,它可能还需要调用其equals
函数。
所以如果这是Moo
:
class Moo(val n: Int) {
override def hashCode() = {
println(s"hashing: $n")
n
}
override def equals(o: Any) = {
println(s"checking equality: $this =?= $o")
o match {
case m: Moo => n == m.n
case _ => false
}
}
override def toString() = s"Moo($n)"
}
然后调用Set.apply
看起来像这样:
val moos = Set(new Moo(1), new Moo(2), new Moo(3), new Moo(4), new Moo(3), new Moo(1), new Moo(2))
// checking equality: Moo(2) =?= Moo(1)
// checking equality: Moo(3) =?= Moo(1)
// checking equality: Moo(3) =?= Moo(2)
// checking equality: Moo(4) =?= Moo(1)
// checking equality: Moo(4) =?= Moo(2)
// checking equality: Moo(4) =?= Moo(3)
// checking equality: Moo(5) =?= Moo(1)
// checking equality: Moo(5) =?= Moo(2)
// checking equality: Moo(5) =?= Moo(3)
// checking equality: Moo(5) =?= Moo(4)
// hashing: 1
// hashing: 2
// hashing: 3
// hashing: 4
// hashing: 5
// hashing: 1
// checking equality: Moo(1) =?= Moo(1)
// hashing: 2
// checking equality: Moo(2) =?= Moo(2)
// moos: scala.collection.immutable.Set[Moo] = Set(Moo(5), Moo(1), Moo(2), Moo(3), Moo(4))
您可以看到,对于添加的每个元素,它会检查它是否与之前的任何元素“相等”;它为前4个元素执行此操作,因为Set.apply
工厂方法具有1-,2-,3-和4-元素类的特殊类。在4之后,它会转换为正常HashSet
,因此它必须散列所有元素。对于每个后续元素,它会散列,然后检查与具有相同散列码的任何现有元素的相等性。
如果您将Moo
定义为case class
,那么您不必定义hashCode
或equals
:编译器会为您执行此操作。