在Java 8中重用流

And*_*ose 5 java java-8 java-stream

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

我从一组对象开始,然后做一些过滤.

Collection<MyClass> collection = /* form the collection */;
Stream<MyClass> myStream = collection.stream().filter(/* some filter */);
Run Code Online (Sandbox Code Playgroud)

然后我想多次重复使用这个相同的流.例如,首先我想从流中获取第一个项目,因此.

MyClass first = myStream.findFirst().get();
Run Code Online (Sandbox Code Playgroud)

然后我做了一些其他的事情,后来我想myStream再次使用过滤来对流中的每个对象执行操作.

myStream.forEach(/* do stuff */);
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试这样做时,我收到此错误.

java.lang.IllegalStateException: stream has already been operated upon or closed
Run Code Online (Sandbox Code Playgroud)

我可以通过执行以下操作之一来解决问题:

  • 从原始集合创建新流并再次对其进行过滤
  • 将流收集到筛选的集合中,然后在其上创建流

所以我想根据我的发现,我有几个问题.

  1. 如果你不能重用流,那么什么时候返回一个流的实例供以后使用会有用吗?
  2. 可以克隆流,以便它们可以重复使用而不会导致IllegalStateException

Mis*_*sha 6

如果你不能重用流,那么什么时候返回一个流的实例供以后使用会有用吗?

如果您有一个返回流的方法,并且您需要该流做两件事,只需调用该方法两次并获得两个不同的流.

可以克隆流,以便可以重用它们而不会导致IllegalStateException吗?

Lambda表达式可以轻松设置,Supplier<Stream>因此您可以避免重建它.如果您所做的只是一个.filter,那么这可能是一种过度杀伤,但对于更复杂的流设置而言,这些设置过于局部化以保证方法,这是一个很好的选择:

Supplier<Stream<MyClass>> sup = () -> collection.stream().....;  /

first = sup.get().findFirst().get(); // do one thing
sup.get().forEach(...);  // do another thing
Run Code Online (Sandbox Code Playgroud)