在Java 8中重用流

时间:2015-07-29 20:52:26

标签: java java-8 java-stream

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

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

Collection<MyClass> collection = /* form the collection */;
Stream<MyClass> myStream = collection.stream().filter(/* some filter */);

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

MyClass first = myStream.findFirst().get();

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

myStream.forEach(/* do stuff */);

然而,当我尝试这样做时,我收到了这个错误。

java.lang.IllegalStateException: stream has already been operated upon or closed

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

      
  • 从原始集合创建新流并再次过滤
  •   
  • 将流收集到已过滤的集合中,然后在该
  • 上创建一个流

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

  1. 如果您无法重新使用流,那么何时返回流的实例以供以后使用会有用吗?
  2. 可以克隆流,以便可以重复使用它们而不会导致IllegalStateException

1 个答案:

答案 0 :(得分: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