I have a class with PriorityQueue field inside:
public class MyClass<T>{
Queue<T> queue = new PriorityQueue<>();
I want somehow get a stream from MyClass and use foreach and want the sequence behave in priority order of my PriorityQueue. The easiest way is to override stream() method:
@Override
public Stream stream() {
return queue.stream();
}
but this will not expose the queue element in priority order. So the question is: how to make foreach stream method behave like:
while(!queue.isEmpty())
queue.poll();
You could use Stream::generate
and Queue::poll
method to get create a Stream
with elements from PriorityQueue
with keeping their order:
@Override
public Stream<T> stream() {
return Stream.generate(queue::poll);
}
However this might be dangerous because Stream::generate
will be invoking poll
constantly so it is potentially an inifinite Stream. Therfore using Stream::limit
with the queue size should be considered :
@Override
public Stream<T> stream() {
return Stream.generate(queue::poll)
.limit(queue.size());
}
Or you could simply return sorted stream :
@Override
public Stream<T> stream() {
return queue.stream()
.sorted(comparator);
}
where comparator is your comparator.
In Java 9 you could use Stream::takeWhile
with predicate that rejects nulls. As Queue::poll
will return null
when queue is empty - the resulting Stream
will contain elements from the queue in their order (this is alternative to using limit
as described in the first solution) :
@Override
public Stream<T> stream() {
return Stream.generate(queue::poll)
.takeWhile(Objects::nonNull);
}