2

誰かが次のことを理解するのを手伝ってくれますか? 要素のツリーマップを作成すると、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
4

3 に答える 3

5

Your intuitive assumption is understandable, but in general TreeSet implementations often rely on comparison methods rather than equality, since the compare operations returns 0 only if the two objects are equal; for Scala, it says so in the doc (compare method).

In Java's TreeSet this is even mentioned explicitly.

In Scala, this is not as obvious from the docs, but if you look at the source code, you'll see that the Scala TreeSet relies on the RedBlackTree implementation internally, which, in its lookup method, uses the result of compare for testing equality exclusively.

And that's perfectly valid, due to Ordering.compare's contract, as noted in the first paragraph - i.e. if you get 0, the two objects are equal by definition.

于 2013-11-08T15:08:37.470 に答える