Есть ли класс в java 8, который реализует поток с нулевым завершением без необходимости сворачивать мои собственные?
Или есть лучший способ сделать это, что я пропал? Я хотел бы создать поток на основе поставщика (который обычно бесконечен), но поток прекращается, когда поставщик возвращает null. Я сделал это сам, но для выполнения довольно простой концепции кажется довольно много работы.
public class NullTerminatedStreamFactory {
static int characteristics = Spliterator.ORDERED | Spliterator.DISTINCT;
public static<T> Stream<T> makeNullTerminatedStream(Supplier<T> supplier) {
return StreamSupport.stream(new NullTerminatedSpliteratorFromSupplier<>(supplier, Long.MAX_VALUE, characteristics), false);
}
static class NullTerminatedSpliteratorFromSupplier<T> extends Spliterators.AbstractSpliterator<T> {
public NullTerminatedSpliteratorFromSupplier(Supplier<T> supplier, long est, int additionalCharacteristics) {
super(est, additionalCharacteristics);
this.supplier = supplier;
}
public Supplier<T> supplier;
@Override
public boolean tryAdvance(Consumer<? super T> action) {
T next = supplier.get();
if (next != null) {
action.accept(next);
return true;
}
return false;
}
}
}
Для записи я использую ее так, чтобы создать Stream из BlockingQueue:
NullTerminatedStreamFactory.makeNullTerminatedStream(() -> {
try {
BlockingQueue<Message> queue = getBlockingQueue();
return queue.poll(1, TimeUnit.SECONDS);
} catch (Exception e) {
log.error("Exception while trying to get message from queue", e);
}
return null;
});
Ответы
Ответ 1
Вы уже нашли совершенно правильную реализацию вручную.
Как упоминалось в комментариях, Java 9, похоже, добавляет метод takeWhile(Predicate)
. До тех пор вы могли бы использовать стороннюю библиотеку, которая реализует нечто вроде takeWhile()
:
jOOλ
jOOλ имеет limitWhile()
, что делает то же самое:
Seq.generate(supplier).limitWhile(Objects::nonNull);
(отказ от ответственности, я работаю в компании за jOOλ)
Javaslang
Javaslang реализовали свой собственный класс Stream
, который вдохновлен коллекциями Scala и, следовательно, имеет takeWhile()
Stream.gen(supplier).takeWhile(Objects::nonNull);
Функциональная Java
Функциональная Java также поставляется со своей собственной реализацией Stream
, которая имеет метод takeWhile()
:
Stream.fromFunction(i -> supplier.get()).takeWhile(o -> o != null);