在Java8中重新使用流

在Java8中重新使用流,java,java-8,java-stream,Java,Java 8,Java Stream,在项目中使用Java流时,我试图重复使用流 我从一组对象开始,然后进行一些过滤 Collection<MyClass> collection = /* form the collection */; Stream<MyClass> myStream = collection.stream().filter(/* some filter */); 然后我做一些其他的事情,然后我想再次使用过滤后的myStream对流中的每个对象执行操作 myStream.forEach(/

在项目中使用Java流时,我试图重复使用流

我从一组对象开始,然后进行一些过滤

Collection<MyClass> collection = /* form the collection */;
Stream<MyClass> myStream = collection.stream().filter(/* some filter */);
然后我做一些其他的事情,然后我想再次使用过滤后的
myStream
对流中的每个对象执行操作

myStream.forEach(/* do stuff */);
然而,当我尝试这样做时,我得到了这个错误

java.lang.IllegalStateException: stream has already been operated upon or closed
我可以通过执行以下操作之一来解决此问题:

  • 从原始集合创建一个新流,并再次对其进行筛选
  • 将流收集到已过滤的集合中,然后在该集合上创建流
因此,根据我的发现,我想我有几个问题

  • 如果不能重用流,那么何时返回流的实例以供以后使用会有用
  • 是否可以克隆流,以便在不引起非法状态异常的情况下重复使用
  • 如果不能重用流,那么何时返回流的实例以供以后使用会有用

    如果您有一个返回流的方法,并且您需要该流做两件事,那么只需调用该方法两次,就可以得到两个不同的流

    是否可以克隆流以便在不导致非法状态异常的情况下重复使用

    Lambda表达式使设置供应商变得容易,因此可以避免重新构建供应商。如果您只做一个
    .filter
    ,这可能是一个过度杀伤力,但对于过于本地而无法保证方法的更复杂的流设置,这是一个很好的选择:

    Supplier<Stream<MyClass>> sup = () -> collection.stream().....;  /
    
    first = sup.get().findFirst().get(); // do one thing
    sup.get().forEach(...);  // do another thing
    
    Supplier sup=()->collection.stream()/
    first=sup.get().findFirst().get();//做一件事
    sup.get().forEach(…);//做另一件事
    
    Supplier<Stream<MyClass>> sup = () -> collection.stream().....;  /
    
    first = sup.get().findFirst().get(); // do one thing
    sup.get().forEach(...);  // do another thing