仅当 allMatch 在 Java 中过滤和处理流一次时才收集流

Ore*_*est 2 java java-stream

我有以下流代码:

List<Data> results = items.stream()
   .map(item -> requestDataForItem(item))
   .filter(data -> data.isValid())
   .collect(Collectors.toList());

Data requestDataForItem(Item item) {
   // call another service here
}
Run Code Online (Sandbox Code Playgroud)

问题是我只想requestDataForItem在流中的所有元素都有效时调用 。例如,如果第一项无效,我不会调用流中的任何元素。

.allMatch流API中,但它返回一个boolean。我想要做的一样.allMatch不是 .collect当一切都匹配的结果。另外,我只想处理一次流,有两个循环很容易。

Java Streams API 可以做到这一点吗?

Hol*_*ger 7

这将是 Java 9 的工作:

List<Data> results = items.stream()
    .map(item -> requestDataForItem(item))
    .takeWhile(data -> data.isValid())
    .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

此操作将在第一个无效元素处停止。在顺序执行中,这意味着不会进行后续requestDataForItem调用。在并行执行中,一些额外的元素可能会在操作停止之前并发处理,但这是高效并行处理的代价。

在任何一种情况下,结果列表都将只包含第一个遇到无效元素之前的元素,您可以使用results.size() == items.size()是否所有元素都有效来轻松检查。


在 Java 8 中,没有这样简单的方法,takeWhile考虑到非流解决方案的简单程度,使用额外的库或推出您自己的实现不会有回报

List<Data> results = new ArrayList<>();
for(Item item: items) {
    Data data = requestDataForItem(item);
    if(!data.isValid()) break;
    results.add(data);
}
Run Code Online (Sandbox Code Playgroud)