java - 将两个 for 重构为 java 8 流
问题描述
我面临一个小问题,将我的两个 for 重写为 java 8 流。
// This is a method parameter
Map<String, Collection<String>> preSelectedValues;
List<PersonModel> parameters = parameterSearchService.getParameterNames();
for(Iterator<Map.Entry<String, Collection<String>>> it = preSelectedValues.entrySet().iterator(); it.hasNext();) {
Map.Entry<String, Collection<String>> entry = it.next();
for(int i = 0; i < parameters.size(); i++) {
if (entry.getKey().startsWith(parameters.get(i).getName())) {
it.remove();
}
}
}
我尝试了以下流以具有与以前相同的行为:
Map<String, Collection<String>> filteredParameters = preSelectedValues.keySet().stream()
.filter(x -> isParameterValid(x, parameters))
.collect(Collectors.toMap(k -> k, v -> preSelectedValues.get(v)));
isParameterValid
方法:
private boolean isParameterValid(String parameterId, List<PersonModel> preSelectedValues) {
return preSelectedValues.stream()
.anyMatch(v -> !v.getName().startsWith(parameterId));
}
基本上我要做的是过滤以“parameterId”开头的“preSelectedValues”映射。但不知何故,当我使用流时,它要么过滤一切,要么什么都不过滤。
解决方案
Your isParameterValid
method doesn't have the same logic as the original loops, since:
- You switched the instance and argument in the call to
startsWith
. - Calling
anyMatch
with a!v.getName().startsWith(parameterId)
only tells you whether at least one element of theList<PersonModel>
doesn't start withparameterId
. Your original condition for keeping the entry in theMap
was that all the elements ofList<PersonModel>
don't start withparameterId
(or actually, the other way around -parameterId
doesn't start with any of the names of elements ofList<PersonModel>
).
Therefore I negated the method to return the condition for removing an entry from the Map
:
private boolean isParameterInvalid(String parameterId, List<PersonModel> preSelectedValues) {
return preSelectedValues.stream()
.anyMatch(v -> parameterId.startsWith(v.getName()));
}
And then the stream pipeline can look like this:
Map<String, Collection<String>> filteredParameters = preSelectedValues.entrySet().stream()
.filter(x -> !isParameterInvalid(x.getKey(), parameters))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
BTW, since your original loops mutate the original Map
, you can achieve the same with removeIf
.
推荐阅读
- swift - 使用单个按钮 swiftUI 的线性/条件导航
- python - 如何连接两个 django 模型查询集
- recursion - 具有匹配模式错误的 F# 递归函数
- python - MATLAB和python对四元数给出不同的答案
- django - 带有 docker-compose 的 VScode 调试器
- groovy - 通过电子邮件发送 JMeter 断言结果时出现 JSON 解析错误
- flutter - 第二次单击颤动列表后删除列表中的选择
- flutter - 在我的自定义 appbar 中访问上下文,它在 Flutter 中扩展 AppBar
- javascript - 在Javascript中将键和值添加到数组中的对象
- c - C 动态结构和成员