是否有解决方法可以从forEach方法"return"流?



说有一个收集需要先修改然后过滤:

Collection<MyObject> collection = ...
Stream<MyObject> dummyVariable = collection.stream();
dummyVariable.forEach(i -> i.callModifyingFunc(args));
return dummyVariable.filter(i -> i.isNeeded);

因为foreach具有void返回类型,不可能在没有dummyVariable的情况下编写代码。是否有任何解决方法可以在一条链中写下全部:

Collection<MyObject> collection = ...
return Stream<MyObject> dummyVariable = collection.stream().forEach(i -> i.callModifyingFunc(args)).filter(i -> i.isNeeded);

只需使用映射而不是foreach链接管道操作:

collection.stream()
          .map(i -> i.callModifyingFunc(args))
          .filter(i -> i.isNeeded);

如果将Stream返回给呼叫者,则无法控制终端操作最终由呼叫者链接。终端操作可能会处理所有元素,但这也可能是短路的,甚至可能完全不使用终端操作而放弃呼叫者。

如果修改的目的只是记录是否已经处理了元素,则peek是正确的选择。

但是,如果您想在任何一种情况下对每个元素进行修改,只需直接进行:

Collection<MyObject> collection = ...
collection.forEach(i -> i.callModifyingFunc(args));
return collection.stream().filter(i -> i.isNeeded);

如果要确保仅在呼叫者开始终端操作时进行修改,则它更为复杂:

Collection<MyObject> collection = ...
Spliterator<MyObject> sp = collection.spliterator();
return StreamSupport.stream(() -> {
        collection.forEach(i -> i.callModifyingFunc(args));
        return sp;
    }, sp.characteristics(), false)
    .filter(i -> i.isNeeded);

这将在流处理开始之前(即执行终端操作之前)对所有元素进行修改。

,但是您应该重新考虑您的要求。必须在流处理之前修改所有元素听起来有问题。如果两个客户获取流?

将会发生什么?

最新更新