具有自定义排序的优先队列
Priority queue with custom ordering
我有这个案例class:
case class Offer(id: Int, amount: Int, interestRate: Double) extends Ordered[Offer] {
def compare(that: Offer) = interestRate.compareTo(that.interestRate)
}
如您所见,我根据 Offer.interestRate
定义了顺序。我希望订单增加。
我创建了这些优惠:
Offer(1, 5, 4.0)
Offer(2, 5, 0.5)
Offer(3, 5, 1.5)
并将它们添加到优先队列中:
val currentOffers: mutable.PriorityQueue[Offer] = mutable.PriorityQueue.empty[Offer]
问题是,当我执行 currentOffers.dequeue()
时,我得到 Offer(1, 5, 4.0)
。
相反,我想得到:
Offer(2, 5, 0.5)
我需要改变什么?
正如其他人在没有太多解释的情况下暗示的那样,问题出在您的比较函数上:
def compare(that: Offer) = this.interestRate.compareTo(that.interestRate)
这与 -1 < 0 < 1 的数字的自然排序相匹配。
当您在 Scala 中创建优先级队列时,它使用一个 Ordering
,它隐含地派生自您定义的 Order
。
您缺少的是优先级队列会将 "higher" 值视为具有最高优先级(基本上它降序排列)。
最简单的解决方法是将 compare
函数更改为它的反函数:
def compare(that: Offer) = that.interestRate.compareTo(this.interestRate)
注意 that
和 this
的倒置。
另一种选择是在构建队列时提供 Ordering
:
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)
这样做的是:"create an ordering for Offers by sorting the interest rate in reverse".
我更喜欢第二个选项,因为它提供了更好的粒度,并允许在必要时使用多个排序。
我有这个案例class:
case class Offer(id: Int, amount: Int, interestRate: Double) extends Ordered[Offer] {
def compare(that: Offer) = interestRate.compareTo(that.interestRate)
}
如您所见,我根据 Offer.interestRate
定义了顺序。我希望订单增加。
我创建了这些优惠:
Offer(1, 5, 4.0)
Offer(2, 5, 0.5)
Offer(3, 5, 1.5)
并将它们添加到优先队列中:
val currentOffers: mutable.PriorityQueue[Offer] = mutable.PriorityQueue.empty[Offer]
问题是,当我执行 currentOffers.dequeue()
时,我得到 Offer(1, 5, 4.0)
。
相反,我想得到:
Offer(2, 5, 0.5)
我需要改变什么?
正如其他人在没有太多解释的情况下暗示的那样,问题出在您的比较函数上:
def compare(that: Offer) = this.interestRate.compareTo(that.interestRate)
这与 -1 < 0 < 1 的数字的自然排序相匹配。
当您在 Scala 中创建优先级队列时,它使用一个 Ordering
,它隐含地派生自您定义的 Order
。
您缺少的是优先级队列会将 "higher" 值视为具有最高优先级(基本上它降序排列)。
最简单的解决方法是将 compare
函数更改为它的反函数:
def compare(that: Offer) = that.interestRate.compareTo(this.interestRate)
注意 that
和 this
的倒置。
另一种选择是在构建队列时提供 Ordering
:
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)
这样做的是:"create an ordering for Offers by sorting the interest rate in reverse".
我更喜欢第二个选项,因为它提供了更好的粒度,并允许在必要时使用多个排序。