仅当allMatch筛选器和流程流在Java中匹配一次时收集流
我有以下流代码:仅当allMatch筛选器和流程流在Java中匹配一次时收集流,java,java-stream,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 } List resu
List<Data> results = items.stream()
.map(item -> requestDataForItem(item))
.filter(data -> data.isValid())
.collect(Collectors.toList());
Data requestDataForItem(Item item) {
// call another service here
}
List results=items.stream()
.map(项目->requestDataForItem(项目))
.filter(数据->数据.isValid())
.collect(Collectors.toList());
数据请求DataForItem(项目){
//在这里呼叫其他服务
}
问题是我想打电话
requestDataForItem
仅当流中的所有元素都有效时。
例如
如果第一项无效,我不想调用流中的任何元素
流API中有.allMatch
,
但它返回一个布尔值。
我想做与.allMatch
相同的事情
。在所有内容匹配时收集结果。
另外,我只想处理流一次,
有了两个循环,这很容易
Java Streams API是否可以实现这一点?实现两步流程:
测试allMatch是否返回true
如果返回true,则使用第二个流执行collect
理论上可以使用.allMatch
然后在返回true时进行收集。allMatch
返回true后,将对收集进行两次处理。无法直接使用streams API执行您正在尝试执行的操作
您可以创建一个方法来完成这项工作,并简单地将集合传递给它,而不是使用流API。与使用流API相比,这稍微不那么优雅,但由于只处理一次集合,因此效率更高
List<Data> results = getAllIfValid(
items.stream().map(item ->
requestDataForItem(item).collect(Collectors.toList())
);
public List<Data> getAllIfValid(List<Data> items) {
List<Data> results = new ArrayList<>();
for (Data d : items) {
if (!d.isValid()) {
return new ArrayList<>();
}
results.add(d);
}
return results;
}
List results=getAllIfValid(
items.stream().map(项->
requestDataForItem(item).collect(Collectors.toList())
);
公共列表getAllIfValid(列表项){
列表结果=新建ArrayList();
用于(数据d:项目){
如果(!d.isValid()){
返回新的ArrayList();
}
结果:添加(d);
}
返回结果;
}
如果每个元素都通过并且只处理一次items
集合,则此操作将返回所有结果。如果任何项未通过isValid()
检查,则它将返回一个空列表,因为您需要全部或全部。只需检查返回的集合是否为空,以查看是否所有项都通过了isValid()
检查。试试这个
List<Data> result = new ArrayList<>();
boolean allValid = items.stream()
.map(item -> requestDataForItem(item))
.allMatch(data -> data.isValid() && result.add(data));
if (!allValid)
result.clear();
List result=new ArrayList();
布尔值allValid=items.stream()
.map(项目->requestDataForItem(项目))
.allMatch(数据->数据.isValid()&&result.add(数据));
如果(!allValid)
result.clear();
这将是Java 9的工作:
List<Data> results = items.stream()
.map(item -> requestDataForItem(item))
.takeWhile(data -> data.isValid())
.collect(Collectors.toList());
只需检查results.size()==items.size()
。谢谢。我已经更新了我的问题。两个步骤的过程很清楚,但它是多余的。谢谢你的想法。API不保证allMatch
会按遭遇顺序计算所有元素。
List<Data> results = new ArrayList<>();
for(Item item: items) {
Data data = requestDataForItem(item);
if(!data.isValid()) break;
results.add(data);
}