scala treeset排序导致元素消失?

时间:2013-11-08 14:56:50

标签: scala

有人可以帮我理解以下内容吗?如果我创建元素的树形图,scala似乎决定我的compare方法也确定元素的相等性,因此根据'compare'方法删除相同的元素。我不期待这个,因为如果我没有覆盖它,那么仍然应该根据对象相等来定义相等吗?

import scala.collection.mutable._

class A(val num: Int) extends Ordered[A] {
    def compare (that: A) = {
        this.num - that.num
    }
    override def toString() = {
      num+""
    }
}

object A {
    def main(args: Array[String]) = {

        val mySet = new TreeSet[A]()
        mySet += new A(3)
        mySet += new A(2)
        mySet += new A(1)
        mySet += new A(3)
        mySet += new A(2)
        mySet += new A(1)

        mySet.foreach(println)
    }
}

给出

1
2
3

不是预期的(由我)

1
1
2
2
3
3

3 个答案:

答案 0 :(得分:4)

您的直观假设是可以理解的,但一般TreeSet实现通常依赖于比较方法而不是相等,因为compare操作仅在两个对象是0时返回等于;对于Scala,它在doccompare方法)中这样说。

在Java的TreeSet中,这甚至是mentioned explicitly

在Scala中,这在文档中并不明显,但是如果你看一下source code,你会发现Scala TreeSet在内部依赖于RedBlackTree实现,其中in its lookup method使用compare的结果专门测试相等性。

这是完全有效的,由于Ordering.compare的合同,如第一段所述 - 即如果你得到0,这两个对象的定义相同。

答案 1 :(得分:2)

来自doc:

“有序[A]的实例的equals方法与compare方法一致是很重要的。但是,由于类型擦除语义中固有的限制,没有合理的方法来提供相等的默认实现对于有序[A]“

的实例

所以你应该提供自己的哈希码,并通过它的外观等于方法。

答案 2 :(得分:0)

据我记忆,SortedSet不允许重复,因此在您的代码中,树的最后一次插入被忽略