当课程没有实现包含时,scala设置重复数据删除是什么?

时间:2015-03-12 20:44:41

标签: scala

假设我有一个通用类Moo,它没有实现contains方法。如果我尝试将此类的5个实例添加到scala MutableSet,它如何知道重复数据删除?

即,如果我创建一个Set(moo1, moo2, moo3, moo4, moo5) Scala使用什么算法来删除重复项?

1 个答案:

答案 0 :(得分:2)

如果你说Set(moo1, moo2, moo3, moo4, moo5),它会创建HashSetMoo个对象。为了确定重复项,它通过调用其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,那么您不必定义hashCodeequals:编译器会为您执行此操作。