octavian octavian - 1 year ago 54
Scala Question

Ordering doesn't hold on SortedSet

I have the following class with a defined ordering:

case class Offer(id: Int, amount: Int, interestRate: Double) extends Ordered[Offer] {

def compare(that: Offer) = that.interestRate.compareTo(this.interestRate)


I declared a SortedSet of
, where I also defined the same ordering:

val currentOffers: SortedSet[Offer] = SortedSet.empty[Offer](Ordering[Double].on[Offer](_.interestRate))

However, if I add:

Offer(1, 5, 4.0)
Offer(2, 5, 0.5)
Offer(3, 5, 1.5)

And then I extract the smallest element using
, I get:

Offer(1, 5, 4.0)

Instead of:

Offer(2, 5, 0.5)

Why is the ordering not respected?

Answer Source

It is respected. min uses the default ordering for the object, which you have supplied, and it orders things backwards (that compare this not this compare that--did you intend that or is this a mistake?). min is not specific to sorted collections--it will work on anything.

If you want to use the supplied ordering, use head: SortedSet's entire point is that it sorts elements from least to greatest. And unlike min, which will check everything just to be sure, head just gets what was already sorted to the front.

That min and head are not necessarily the same on SortedSet is a little nonintuitive, admittedly, but there is at least a bit of justification for why.