这是课程项目。
public class Item {
String id;
String name;
Integer value;
Boolean status;
}
我有一个Map(String,Set(Item))。我想编写一个返回Map(String,Set(Item))的方法,以便在结果映射中只存在status = false或status = null的Items。我不想要一个集合范围的操作。我希望结果子集只包含那些状态为== Boolean.FALSE或status == null的Item。我不希望整个集合被包含或排除。我只希望根据状态值包含或排除这些单独的项目。
这是我迄今为止所尝试的内容。
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));
}
它没有用!如果我没有调用filterByStatus,我会得到与之相同的结果。
更新
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));
}
结果:collect(Collectors.toMap())行中出现错误,说明无法从静态上下文引用非静态方法。
答案 0 :(得分:3)
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())
));
}
答案 1 :(得分:2)
对于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;
}
如果集合是可变的并且您不再需要旧状态,您甚至可以就地进行操作:
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);
你甚至可以删除这些项目,然后只有当它们因删除而变为空时删除它,在一个声明中:
changes.values().removeIf(set ->
set.removeIf(item -> Boolean.TRUE.equals(item.status)) && set.isEmpty());
答案 2 :(得分:0)
根据您的说明,您正在寻找allMatch
而不是anyMatch
。
目前,您获得的所有集合至少包含一个非True值。您似乎想要的只是只包含非True值的集合。
如果您正在寻找过滤掉所有集合中的负值,则应在地图上使用映射,而不仅仅是过滤器。在映射中,您可以创建除去True值的集合的副本。
答案 3 :(得分:0)
这可以避免在新地图中包含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()))
);
}