为了账号安全,请及时绑定邮箱和手机立即绑定

使用 Stream StreamSupplier

使用 Stream StreamSupplier

蓝山帝景 2021-05-31 10:35:17
我正在使用以下代码重用 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();    }}
查看完整描述

3 回答

?
胡子哥哥

TA贡献1825条经验 获得超6个赞

不要分配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)

    .peek(System.out::println)

    .count();


查看完整回答
反对 回复 2021-06-02
?
一只甜甜圈

TA贡献1836条经验 获得超5个赞

Stream::count是关闭流的终端操作,因此没有更多的管道可以继续。

你创建Stream<String>你把它放到之前Supplier。如果您希望供应商在每次调用时提供一个新的 Stream,请Stream<String>直接在Supplier.

Supplier<Stream<String>> streamSupplier = () -> Stream.of(array);

然后streamSupplier.get()将始终使用新的Stream<Stream>.


但是,您可能会获得相同的结果,Stream::peek其工作方式相同Stream::forEach,但不关闭Stream但返回相同的未修改结果(@Lino 更快)。

long count = streamSupplier.get().peek(System.out::println).count();


查看完整回答
反对 回复 2021-06-02
?
尚方宝剑之说

TA贡献1788条经验 获得超4个赞

你得到的例外是合适的,它告诉你需要研究什么。从Java 8 Stream 类

一个流应该只被操作一次(调用一个中间或终端流操作)。例如,这排除了“分叉”流,其中相同的源提供两个或多个管道,或者同一流的多次遍历。如果流实现检测到流正在被重用,它可能会抛出 IllegalStateException。但是,由于某些流操作可能会返回其接收器而不是新的流对象,因此可能无法在所有情况下检测到重用。


查看完整回答
反对 回复 2021-06-02
  • 3 回答
  • 0 关注
  • 289 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信