还是有更好的方法来做到这一点我失踪了?我想创建一个基于供应商(通常是无限制)的流,但是当供应商返回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; } } }
为了记录,我正在使用它,基本上从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; });
解决方法
您已经找到了完美有效的手工实现.
如评论中所述,Java 9似乎添加了一个takeWhile(Predicate)
方法.在此之前,您可以使用实现类似takeWhile()的第三方库:
jOOλ
jOOλ有limitWhile(),它做同样的事情:
Seq.generate(supplier).limitWhile(Objects::nonNull);
(免责声明,我为jOOλ之后的公司工作)
Javaslang
Javaslang实现了自己的Stream类,它受到Scala集合的启发,因此带有Widget()
Stream.gen(supplier).takeWhile(Objects::nonNull);
功能Java
Functional Java还配有自己的Stream实现,那有一个takeWhile()方法:
Stream.fromFunction(i -> supplier.get()).takeWhile(o -> o != null);