这两段代码具有不同的输出顺序。 第一篇:
while(!jobQueue.isEmpty()) {
TimeoutJobRequest job = jobQueue.peek();
if(job.isReady()) {
execute(job);
jobQueue.poll();
} else {
return;
}
}
第二部分:
jobQueue.stream()
.filter(TimeoutJobRequest::isReady)
.peek(jobQueue::remove)
.forEach(this::execute);
请注意,jobQueue
是PriorityBlockingQueue
。
重新排序仅在this::execute
相对较长时(例如几秒钟)发生。
答案 0 :(得分:7)
stream
的{{1}}遵循PriorityBlockingQueue
顺序,根据documentation:
不保证方法iterator()中提供的迭代器 遍历任何特定的PriorityBlockingQueue的元素 顺序。
如果您想要优先顺序,则需要Iterator
poll
中的元素。
PriorityBlockingQueue
输出(可能取决于Java实现):
PriorityBlockingQueue<Integer> pq = new PriorityBlockingQueue<>();
pq.add(5);
pq.add(8);
pq.add(3);
System.out.println("-- Try 1 --");
pq.stream().forEach(System.out::println);
System.out.println("-- Try 2 --");
IntStream.range(0, pq.size()).map(i -> pq.poll()).forEach(System.out::println);
答案 1 :(得分:4)
如果要创建遵循队列顺序的流,可以尝试以下代码(它清空队列):
Stream.generate(jobQueue::poll).limit(jobQueue.size())
答案 2 :(得分:1)
第一段代码不等于第二段代码,当job.isReady()
函数返回false
时,第一段代码终止,但第二段仍然运行,函数filter
为stream只是一个过滤操作
您可以将第一段代码更改为
while(!jobQueue.isEmpty()) {
TimeoutJobRequest job = jobQueue.peek();
if(job.isReady()) {
execute(job);
jobQueue.poll();
}
}
答案 3 :(得分:0)
不幸的是,迭代顺序!=优先顺序。
我准备了两个可复制粘贴的解决方案,使用Stream API使用优先级顺序遍历PriorityQueue
:
static <T> Stream<T> drainToStream(PriorityQueue<T> queue) {
Objects.requireNonNull(queue);
return Stream.generate(queue::poll)
.limit(queue.size());
}
static <T> Stream<T> asStream(PriorityQueue<T> queue) {
Objects.requireNonNull(queue);
Comparator<? super T> comparator = queue.comparator();
return comparator != null
? queue.stream().sorted(comparator)
: queue.stream().sorted();
}
draintToStream
清空队列,而asStream
保持原始队列不变。