[英]Java 8 Strem filter map in map — Map<String,Map<String,Employee>>
How to filter a Map<String,Map<String,Employee>>
using Java 8 Filter? 如何使用Java 8 Filter过滤
Map<String,Map<String,Employee>>
?
I have to filter only when any of employee in the list having a field value Gender = "M". 我必须仅在列表中具有字段值Gender =“M”的任何员工时进行过滤。
Input: 输入:
Map<String,Map<String,Employee>>
Output: 输出:
Map<String,Map<String,Employee>>
Filter criteria: 过滤标准:
Employee.genter = "M"
Also i have to return empty map if the filtered result is empty. 如果过滤结果为空,我还必须返回空地图。
I tried the below, but it is not working as expected. 我尝试了以下,但它没有按预期工作。 It is returning the only if all the Employees are with gender "M".
如果所有员工都是性别“M”,则返回。
tempCollection.entrySet().stream()
.filter(i -> i.getValue().entrySet().stream().allMatch(e-> "M".equals(e.getValue().getGender())))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
You could simply iterate on the key-value pairs and filter as: 您可以简单地迭代键值对并过滤为:
Map<String, Map<String, Employee>> output = new HashMap<>();
tempCollection.forEach((k, v) -> {
if (v.values().stream().anyMatch(i -> "M".equals(i.getGender()))) {
output.put(k, v.entrySet()
.stream()
.filter(i -> "M".equals(i.getValue().getGender()))
.collect(toMap(Map.Entry::getKey, Map.Entry::getValue)));
}
});
Seems like what you're after is given a Entry<String,Map<String,Employee>>
if there's any employee who has a gender of "M" then filter the inner Map<String,Employee>
to contain only entries with a gender "M". 如果有任何员工的性别为“M”,则过滤内部
Map<String,Employee>
以仅包含具有性别的条目,看起来像您所获得的Entry<String,Map<String,Employee>>
“M”。
in which case you can filter
along with anyMatch
for the first criterion. 在这种情况下,您可以与
anyMatch
一起filter
第一个标准。 Further, at the collecting phase, you can then apply the filtering on the inner map: 此外,在收集阶段,您可以在内部地图上应用过滤:
tempCollection.entrySet().stream()
.filter(i -> i.getValue().values().stream().anyMatch(e -> "M".equals(e.getGender())))
.collect(toMap(Map.Entry::getKey,
v -> v.getValue().entrySet().stream()
.filter(i -> "M".equals(i.getValue().getGender()))
.collect(toMap(Map.Entry::getKey, Map.Entry::getValue))));
The function allMatch
only matches if every element in the stream matches the predicate; 函数
allMatch
仅匹配流中的每个元素与谓词匹配; you can use anyMatch
to match if any element matches the predicate: 如果任何元素与谓词匹配,您可以使用
anyMatch
匹配:
tempCollection.entrySet().stream()
.filter(i -> i.getValue().entrySet().stream().anyMatch(e-> "M".equals(e.getValue().getGender())))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
You may do it like so, 你可以这样做,
Map<String, Map<String, Employee>> maleEmpMap = tempCollection.entrySet().stream()
.map(e -> new AbstractMap.SimpleEntry<>(e.getKey(),
e.getValue().entrySet().stream().filter(emp -> "M".equals(emp.getValue().getGender()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
Take each map entry from the outer map and create a new map entry using the same key and the newly constructed nested map with the same key and which has only male employees as it's value. 从外部地图中获取每个地图条目,并使用相同的密钥创建新的地图条目,并使用相同的密钥创建新的嵌套地图,并且只有男性员工作为其值。 Finally collect all those matching entries into a new outer map.
最后将所有匹配的条目收集到新的外部地图中。 This will gracefully handle the empty scenario which you mentioned in the problem statement above.
这将优雅地处理您在上面的问题陈述中提到的空场景。
Other way would be like this: 其他方式是这样的:
map.values()
.removeIf(entry->entry.values().stream().anyMatch(e -> !"M".equals(e.getGender())));
map.entrySet()
.removeIf(entry->entry.getValue().size() == 0);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.