使用 Stream StreamSupplier

我正在使用以下代码重用 Stream 但得到


java.lang.IllegalStateException: 流已经被操作或关闭


代码


public static void main(String[] args) {


    try {

        String[] array = { "a", "b", "c", "d", "e" };

        Stream<String> ss = Stream.of(array);

        Supplier<Stream<String>> streamSupplier = () -> ss;


        long count = streamSupplier.get().count();

        // get new stream

        streamSupplier.get().forEach(x -> System.out.println(x));


        // get another new stream


        System.out.println(count);

    } catch (Exception e) {

        e.printStackTrace();

    }

}


蓝山帝景
浏览 290回答 3
3回答

胡子哥哥

不要分配Stream.of(array)给中间变量,只需直接在Supplier:Supplier<Stream<String>> streamSupplier = () -> Stream.of(array);那是因为以前您只会在调用时始终提供相同的引用,supplier.get()但实际上您想返回一个新的Stream.同样正如@Eugene 所建议的,使用Arrays.stream()overStream.of()是首选。因为后者是一个可变参数方法,但只是委托给前者。也可以使用以下Stream.peek()方法简化您当前的方法:long count = Arrays.stream(array)&nbsp; &nbsp; .peek(System.out::println)&nbsp; &nbsp; .count();

一只甜甜圈

Stream::count是关闭流的终端操作,因此没有更多的管道可以继续。你创建Stream<String>你把它放到之前Supplier。如果您希望供应商在每次调用时提供一个新的 Stream,请Stream<String>直接在Supplier.Supplier<Stream<String>>&nbsp;streamSupplier&nbsp;=&nbsp;()&nbsp;->&nbsp;Stream.of(array);然后streamSupplier.get()将始终使用新的Stream<Stream>.但是,您可能会获得相同的结果,Stream::peek其工作方式相同Stream::forEach,但不关闭Stream但返回相同的未修改结果(@Lino 更快)。long&nbsp;count&nbsp;=&nbsp;streamSupplier.get().peek(System.out::println).count();

尚方宝剑之说

你得到的例外是合适的,它告诉你需要研究什么。从Java 8 Stream 类:一个流应该只被操作一次(调用一个中间或终端流操作)。例如,这排除了“分叉”流,其中相同的源提供两个或多个管道,或者同一流的多次遍历。如果流实现检测到流正在被重用,它可能会抛出 IllegalStateException。但是,由于某些流操作可能会返回其接收器而不是新的流对象,因此可能无法在所有情况下检测到重用。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java