J.J*_*eam 2 java priority-queue java-stream
我有一个里面有 PriorityQueue 字段的类:
public class MyClass<T>{
Queue<T> queue = new PriorityQueue<>();
Run Code Online (Sandbox Code Playgroud)
我想以某种方式从 MyClass 获取一个流并使用 foreach 并希望序列按照我的 PriorityQueue 的优先级顺序运行。最简单的方法是覆盖 stream() 方法:
@Override
public Stream stream() {
return queue.stream();
}
Run Code Online (Sandbox Code Playgroud)
但这不会按优先级顺序公开队列元素。所以问题是:如何让 foreach 流方法表现得像:
while(!queue.isEmpty())
queue.poll();
Run Code Online (Sandbox Code Playgroud)
您可以使用Stream::generateandQueue::poll方法来创建一个Streamwith 元素PriorityQueue 并保持它们的顺序:
@Override
public Stream<T> stream() {
return Stream.generate(queue::poll);
}
Run Code Online (Sandbox Code Playgroud)
然而,这可能是危险的,因为它Stream::generate会poll不断地调用,所以它可能是一个无限的流。因此Stream::limit应考虑与队列大小一起使用:
@Override
public Stream<T> stream() {
return Stream.generate(queue::poll)
.limit(queue.size());
}
Run Code Online (Sandbox Code Playgroud)
或者你可以简单地返回排序流:
@Override
public Stream<T> stream() {
return queue.stream()
.sorted(comparator);
}
Run Code Online (Sandbox Code Playgroud)
其中比较器是您的比较器。
在Java 9 中,您可以使用Stream::takeWhilewith 拒绝空值的谓词。正如Queue::poll将返回null时队列为空-所得Stream将包含在它们的顺序从队列中的元素(这是另一种使用limit如在第一溶液中所述):
@Override
public Stream<T> stream() {
return Stream.generate(queue::poll)
.takeWhile(Objects::nonNull);
}
Run Code Online (Sandbox Code Playgroud)