流如何停止?

口译员

我想知道何时创建自己的无限流以及Stream.generate标准库中的如何停止...

例如,当您有一个包含记录的列表时:

List<Record> records = getListWithRecords();
records.stream().forEach(/* do something */);

流不会是无限的并永远运行,但是当遍历列表中的所有项目时,流将停止。但是,如何运作?相同的功能适用于创建的流Files.lines(path)(来源:http : //www.mkyong.com/java8/java-8-stream-read-a-file-line-by-line/)。

第二个问题是:如何用Stream.generate相同的方式停止使用创建的流

霍尔格

有限流根本不是通过创建的Stream.generate

实现数据流的标准方法,是实现Spliterator,有时使用Iterator弯路在这两种情况下,实现都有一种方法来报告结束,例如,当Spliterator.tryAdvancereturnfalse或其forEachRemaining方法刚刚返回时,或者在Iterator源的情况下,当hasNext()return时false

ASpliterator甚至可以在处理开始之前报告预期的元素数量。

通过Stream接口内部的一种工厂方法创建的流,Stream.generate也可以通过Spliterator流实现或使用流实现的内部功能来实现,但是无论如何实现,都无法实现更改其行为,因此使此类流有限的唯一方法是将limit操作链接到该流。

如果要创建不由数组或集合支持的非空有限流,并且现有的流源都不适合,则必须实现自己的流Spliterator从中创建流如上所述,您可以使用现有方法从中创建Spliteratorout Iterator,但是您应该避免使用Iteratorjust的诱惑是因为它很熟悉。一个Spliterator并不难实现:

/** like {@code Stream.generate}, but with an intrinsic limit */
static <T> Stream<T> generate(Supplier<T> s, long count) {
    return StreamSupport.stream(
               new Spliterators.AbstractSpliterator<T>(count, Spliterator.SIZED) {
        long remaining=count;

        public boolean tryAdvance(Consumer<? super T> action) {
            if(remaining<=0) return false;
            remaining--;
            action.accept(s.get());
            return true;
        }
    }, false);
}

从这个起点开始,您可以添加接口default方法的替代Spliterator,权衡开发费用和潜在的性能改进,例如

static <T> Stream<T> generate(Supplier<T> s, long count) {
    return StreamSupport.stream(
               new Spliterators.AbstractSpliterator<T>(count, Spliterator.SIZED) {
        long remaining=count;

        public boolean tryAdvance(Consumer<? super T> action) {
            if(remaining<=0) return false;
            remaining--;
            action.accept(s.get());
            return true;
        }

        /** May improve the performance of most non-short-circuiting operations */
        @Override
        public void forEachRemaining(Consumer<? super T> action) {
            long toGo=remaining;
            remaining=0;
            for(; toGo>0; toGo--) action.accept(s.get());
        }
    }, false);
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章