Reputation: 20222
I have this case class:
case class Offer(id: Int, amount: Int, interestRate: Double) extends Ordered[Offer] {
def compare(that: Offer) = interestRate.compareTo(that.interestRate)
}
As you can see, I defined the ordering based upon Offer.interestRate
. I want the ordering to be increasing.
I created these offers:
Offer(1, 5, 4.0)
Offer(2, 5, 0.5)
Offer(3, 5, 1.5)
and added them to a priority queue:
val currentOffers: mutable.PriorityQueue[Offer] = mutable.PriorityQueue.empty[Offer]
The problem is that when I do currentOffers.dequeue()
I get Offer(1, 5, 4.0)
.
Instead, I would like to get:
Offer(2, 5, 0.5)
What do I need to change?
Upvotes: 2
Views: 4365
Reputation: 3469
As others hinted without much explaining, the problem is your comparison function:
def compare(that: Offer) = this.interestRate.compareTo(that.interestRate)
This matches the natural ordering for numbers where -1 < 0 < 1.
When you create a priority queue in Scala it uses an Ordering
which is implicitly derived from the Order
you've defined.
The thing that you're missing is that the priority queue will consider the "higher" value as having the highest priority (basically it sorts descending).
The easiest fix for this would be to change the compare
function to its inverse:
def compare(that: Offer) = that.interestRate.compareTo(this.interestRate)
Note the inversion of that
and this
.
Another option would be to provide the Ordering
when building the queue:
val q = mutable.PriorityQueue(
Offer(1, 5, 4.0),
Offer(2, 5, 0.5),
Offer(3, 5, 1.5)
)(Ordering.by[Offer, Double](_.interestRate).reverse)
What this does is: "create an ordering for Offers by sorting the interest rate in reverse".
I like the second option better because it provides better granularity and allows to have multiple orderings used when necessary.
Upvotes: 7