TPriorityQueue[A] 是一个可以参与 STM 事务的可变队列。一个 TPriorityQueue 中包含了类型为 A 的带有顺序定义的值。与 TQueue 不同,take 返回的是最高优先级(指定顺序中的第一个)值,而不是队列中的第一个值。当从队列中取出时,不保证共享相同优先级的元素的顺序。
创建一个 TPriorityQueue
您可以使用 empty 函数创建一个空的 TPriorityQueue:
import zio._
import zio.stm._
val minQueue: STM[Nothing, TPriorityQueue[Int]] =
TPriorityQueue.empty
请注意,TPriorityQueue 的创建使用了隐式 Ordering。默认情况下,take 将返回指定顺序中第一个的值。例如,在按时间排序的事件队列中,最早的事件将被首先取出。如果您想要不同的行为,可以使用自定义的 Ordering。
val maxQueue: STM[Nothing, TPriorityQueue[Int]] =
TPriorityQueue.empty(Ordering[Int].reverse)
您还可以使用 fromIterable 或 make 构造函数创建一个使用指定元素初始化的TPriorityQueue。fromIterable 构造函数采用 Iterable,而 make 构造函数采用可变参数元素序列。
向 TPriorityQueue 添加元素
您可以使用 offer 或 offerAll 方法将元素添加入 TPriorityQueue。如果您要同时向队列添加多个元素,则 offerAll 方法会更加高效。
val queue: STM[Nothing, TPriorityQueue[Int]] =
for {
queue <- TPriorityQueue.empty[Int]
_ <- queue.offerAll(List(2, 4, 6, 3, 5, 6))
} yield queue
从 TPriorityQueue 中获取元素
使用 take 从 TPriorityQueue 中获取一个元素。take 在语义上会阻塞,直到队列中至少要取一个值为止。您还可以使用 takeAll 立即获取队列中当前的所有值,或使用 takeUpTo 立即获取队列中指定数量的元素。
val sorted: STM[Nothing, Chunk[Int]] =
for {
queue <- TPriorityQueue.empty[Int]
_ <- queue.offerAll(List(2, 4, 6, 3, 5, 6))
sorted <- queue.takeAll
} yield sorted
您也可以使用 takeOption 方法从队列中获取第一个值(如果不存在也不会被挂起),或者使用 peek 方法观察队列中的第一个元素(如果存在)而不将其从队列中删除。
有时,您想要对队列的当前状态进行快照而不修改它。为此,toChunk 组合器或其变体 toList 或 toVector 非常有用。这些函数将返回一个不可变的集合,该集合由当前队列中的所有元素组成,而队列的状态保持不变。
TPriorityQueue 的大小
您可以使用 size 方法检查 TPriorityQueue 的大小:
val size: STM[Nothing, Int] =
for {
queue <- TPriorityQueue.empty[Int]
_ <- queue.offerAll(List(2, 4, 6, 3, 5, 6))
size <- queue.size
} yield size