首页 > 解决方案 > Stream 已被供应商操作或关闭

问题描述

我想在我的方法中重用流对象,但是当我第二次从供应商那里调用时,我看到流已经被操作或关闭错误。

private Stream<User> getUserStream(Stream<User> testStream) { 
    Supplier<Stream<User>> supplierUserStream=()->userStream;
    supplierUserStream.get().sorted();
    supplierUserStream.get().sorted();// throw exception Stream has already been operated upon or closed
    return userStream;
}

我不想将流转换为列表。我看到很多这样的例子。

Supplier<Stream<User>> streamSupplier
        = () -> Stream.of(userStream.toArray(size -> new User[size]));

标签: javajava-stream

解决方案


仔细查看消息(强调我的):

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

由于您的第一个语句中没有终端操作,因此您的流尚未关闭而是已对其进行操作,这就是您在第二次尝试对其进行操作时遇到错误的原因。

您可以按如下方式更改它以消除错误:

supplierUserStream.get().sorted().sorted();

在线演示

但是,这将是一种隐藏潜在问题的方法,例如,如果您将 test 调用替换main为以下语句,您将再次遇到相同的问题:

getStringStream(Stream.of("Hello", "World")).forEach(System.out::println);

处理它的好方法可以由ernest_k建议:

它也可以通过跟踪派生的流对象来解决。流流 = s.get().sorted(); 流 = stream.sorted(); return stream.sorted();,以重用那些多余的 sort() 调用。

演示:

import java.util.function.Supplier;
import java.util.stream.Stream;

public class Main {
    public static void main(String[] args) {
        getStringStream(Stream.of("World", "Hello", "Good morning!")).forEach(System.out::println);
    }

    private static Stream<String> getStringStream(Stream<String> testStream) {
        Supplier<Stream<String>> supplierStringStream = () -> testStream;
        Stream<String> stream = supplierStringStream.get().sorted();
        return stream.sorted();
    }
}

输出:

Good morning!
Hello
World

推荐阅读