Reputation: 518
Let's say you have the following:
case class Foo(x: Int, y: Int) extends Ordered[Foo] {
override def compare(that: Foo): Int = x compareTo that.x
}
val mutableSet: scala.collection.mutable.SortedSet[Foo] =
scala.collection.mutable.SortedSet(Foo(1, 2), Foo(1,3))
I expect the result of mutableSet.size
to be 2
. Why, Foo(1,2)
and Foo(1,3)
are not equal but they have the same ordering. So the sorted set should be (IMO) Foo(1,2), Foo(1,3)
. As this is the order they were created in (even the other way around would be fine, counter intuitive but fine).
However, the result of mutableSet.size
is 1
and it saves the last value i.e. Foo(1,3)
.
What am I missing?
Upvotes: 2
Views: 282
Reputation: 5344
The behavior is similar to the Java SortedSet collections. SortedSet
uses compareTo in order to define equality, thus it eliminates the same Foo case classes from your example.
In Scala 2.11 it uses scala.collection.TreeSet
for the implementation SortedSet implementation. The best way to figure out this is to put breakpoint into your compareTo
method.
TreeSet is implemented using AVL Tree data structure, you can inspect the behavior by looking into the AVLTree.scala insert method of the Node class. It compare compareTo
result with 0 in order to figure out does it duplicated element in the collection.
Upvotes: 3
Reputation: 10428
You have overridden compare
so that only the first field is used in comparison. The Set uses this compare
function not just to sort the items but also to determine if the items are equal for the purpose of storing them in the Set
.
Upvotes: 2