我希望这是基于价格的顺序......
final case class Case(price: Int) {}
但它实际上是一个非常大的案例类,我从中删除了字段。我想这样排序......
val queue = PriorityQueue.empty[Case](Ordering.by((_: Case).price).reverse)
^按降价排序。
现在我希望排序保持......
queue.enqueue(Case(price = 2))
println(queue.toString)
queue.enqueue(Case(price = 3))
println(queue.toString)
queue.enqueue(Case(price = 4))
println(queue.toString)
queue.enqueue(Case(price = 1))
println(queue.toString)
queue.enqueue(Case(price = 0))
println(queue.toString)
但我的输出并没有排在第四和第五行...
PriorityQueue(Case(2))
PriorityQueue(Case(2), Case(3))
PriorityQueue(Case(2), Case(3), Case(4))
PriorityQueue(Case(1), Case(2), Case(4), Case(3))
PriorityQueue(Case(0), Case(1), Case(4), Case(3), Case(2))
此外,foreach
方法不是按顺序迭代......
queue.foreach{ q =>
print(q + ", ")
}
...打印
Case(0), Case(1), Case(4), Case(3), Case(2),
如何让我的队列按降价排序?
答案 0 :(得分:5)
根据Scala Documentation,打印队列不会显示优先级:
只有dequeue和dequeueAll方法才会返回方法 优先顺序(从堆中删除元素)。标准 收集方法包括drop,iterator和toString将删除 或者以最方便的顺序遍历堆。
因此,打印PriorityQueue不会显示优先顺序 虽然会打印出最高优先级的元素 第一。要按顺序打印元素,必须复制元素 PriorityQueue(例如,使用clone),然后将它们出列
因此,如果您想按顺序查看元素,则需要这样的内容:
scala> val queue = PriorityQueue.empty[Case](Ordering.by((_: Case).price).reverse)
queue: scala.collection.mutable.PriorityQueue[Case] = PriorityQueue()
scala> queue += Case(2) += Case(3) += Case(4) += Case(1) += Case(0)
res1: queue.type = PriorityQueue(Case(0), Case(1), Case(4), Case(3), Case(2))
scala> while (queue.size > 0) println(queue.dequeue)
Case(0)
Case(1)
Case(2)
Case(3)
Case(4)
或者您可以使用dequeueAll
获取有序集合:
scala> val queue = PriorityQueue.empty[Case](Ordering.by((_: Case).price).reverse)
queue: scala.collection.mutable.PriorityQueue[Case] = PriorityQueue()
scala> queue += Case(2) += Case(3) += Case(4) += Case(1) += Case(0)
res2: queue.type = PriorityQueue(Case(0), Case(1), Case(4), Case(3), Case(2))
scala> val ordered = queue.dequeueAll
ordered: scala.collection.immutable.IndexedSeq[Case] = Vector(Case(0), Case(1), Case(2), Case(3), Case(4))
scala> ordered.foreach(println)
Case(0)
Case(1)
Case(2)
Case(3)
Case(4)
基于讨论 here,没有办法按顺序检索元素而不会通过出列来破坏队列。这似乎是底层数据结构(二进制堆)的实现所固有的。
答案 1 :(得分:1)
打印优先级队列可能不会返回订单中的元素。
但保证的是head
始终返回最低(根据您的排序)元素,并按dequeue
指定的顺序重复Ordering
个出列元素。
当我这样做时:
queue.dequeue()
queue.dequeue()
queue.dequeue()
queue.dequeue()
queue.dequeue()
我明白了:
res10: Case = Case(0)
res11: Case = Case(1)
res12: Case = Case(2)
res13: Case = Case(3)
res14: Case = Case(4)
答案 2 :(得分:0)
是的,当优先级队列元素相等时,scala默认实现不是就地出队。您可以使用就地出队作为打击:
class PriorityQueueTest{
implicit val ord: Ordering[(Any,Int)] = Ordering.by(_._2)
var queue = mutable.PriorityQueue[(Any,Int)]()
def inplaceDeque(number:Int): Seq[(Any,Int)] ={
var res: Seq[(Any,Int)] = Seq()
res =queue.take(number).toSeq
queue =queue.drop(number)
res
}
}