[英]Filtering with Java 8: Map<String, Set<Object>> from Map<String, Set<Object>> based on an attribute of Object
This is class Item. 这是类Item。
public class Item {
String id;
String name;
Integer value;
Boolean status;
}
I have a Map(String, Set(Item)). 我有一个Map(String,Set(Item))。 I want to write a method that returns a Map(String, Set(Item)) such that only Items with status = false or status = null are present in the resulting map.
我想编写一个返回Map(String,Set(Item))的方法,以使结果映射中仅包含status = false或status = null的Items。 I don't want a set-wide operation.
我不要设置范围内的操作。 I want the resulting subsets to only contain those Item that have status == Boolean.FALSE OR status == null.
我希望结果子集仅包含状态== Boolean.FALSE或状态== null的那些项。 I don't want the entire set to get included or excluded.
我不希望整个集合都包含在内或排除在外。 I only want those individual items included or excluded as per the status value.
我只希望根据状态值包括或排除那些单独的项目。
Here's what I've tried so far. 到目前为止,这是我尝试过的。
public Map<String,Set<Item>> filterByStatus(Map<String, Set<Item>> changes) {
return changes.entrySet()
.stream()
.filter(p -> p.getValue()
.stream()
.anyMatch(item -> BooleanUtils.isNotTrue(item.isStatus())))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}
It didn't work! 没用! I get back the same results as I would if I didn't call filterByStatus.
我得到的结果与不调用filterByStatus时得到的结果相同。
UPDATE UPDATE
public Map<String,Set<Item>> filterByStatus(Map<String, Set<Item>> changes) {
return changes.entrySet()
.stream()
.map(p -> p.getValue()
.stream()
.filter(item -> BooleanUtils.isNotTrue(item.isStatus())))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}
Result: There's an error in the collect(Collectors.toMap()) line saying Non-static method cannot be referenced from static context. 结果:collect(Collectors.toMap())行中出现错误,表明无法从静态上下文中引用非静态方法。
public Map<String, Set<Item>> filterByStatus(Map<String, Set<Item>> changes) {
return changes.entrySet()
.stream()
.collect(Collectors.toMap(Map.Entry::getKey, entry ->
entry.getValue()
.stream()
.filter(item -> item.status == null || item.status == Boolean.FALSE)
.collect(Collectors.toSet())
));
}
Alternatively to a Stream solution, you may use 除了Stream解决方案,您可以使用
public Map<String, Set<Item>> filterByStatus(Map<String, Set<Item>> changes) {
Map<String, Set<Item>> result = new HashMap<>(changes);
result.replaceAll((key, set) -> {
set = new HashSet<>(set);
set.removeIf(item -> Boolean.TRUE.equals(item.status));
return set;
});
// if you want to remove empty sets afterwards:
result.values().removeIf(Set::isEmpty);
return result;
}
You could even do the operation in-place if the sets are mutable and you don't need the old state anymore: 如果集合是可变的并且您不再需要旧状态,您甚至可以就地进行操作:
changes.values().forEach(set -> set.removeIf(item -> Boolean.TRUE.equals(item.status)));
// if you want to remove empty sets afterwards (and the map is mutable):
changes.values().removeIf(Set::isEmpty);
you could even remove these items, followed by removing the set only if they became empty due to the removal, in one statement: 您甚至可以删除这些项,然后仅在一条语句中由于删除而使它们变空的情况下删除该集合:
changes.values().removeIf(set ->
set.removeIf(item -> Boolean.TRUE.equals(item.status)) && set.isEmpty());
Judging from your description you are looking for allMatch
rather than anyMatch
. 从您的描述来看,您正在寻找
allMatch
而不是anyMatch
。
Currently you get all the sets which contain at least one non-True value. 当前,您获得的所有集合至少包含一个非True值。 What you seem to want is having only sets that consist of non-True values only.
您似乎想要的是仅具有仅包含非True值的集合。
If you are rather looking for filtering out the negative values from all sets, you should use a mapping, not just filter, on the Map. 如果您想从所有集合中滤除负值,则应在Map上使用映射,而不仅仅是过滤。 In the mapping you could create copies of the sets with True values excluded.
在映射中,您可以创建不包含True值的集合的副本。
This avoid include in new Map entrys with 0 items. 这样可以避免将新地图条目包含在0个项目中。
private Map<String,Set<Item>> filterByStatus(Map<String, Set<Item>> changes) {
return changes.entrySet()
.stream()
.filter(entry -> entry.getValue()
.stream()
.anyMatch(item -> item.status == null || item.status == false))
.collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue()
.stream()
.filter(item -> item.status == null || item.status == false)
.collect(Collectors.toSet()))
);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.