我有一张地图
Map<Integer, List<Person>> personsById
和谓词函数callbak
(person) -> person.getPersonID() > 10 && person.blabla() !=null
我需要根据谓词过滤地图,我想出了下面不修改List的代码
map.entrySet().stream()
.filter(entry -> entry.getValue().stream().anyMatch(predicate))
.collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue))
但是上面的代码实际上并没有过滤List
分机:{id: 100, [{personID: 100}, {personID: 50}, {personID: 2}]
我仍然可以在列表中看到personID: 2
。有没有办法可以修改列表中的值以返回过滤后的列表或人员? java 8中的任何指针都非常有用。
P.s:Plz忽略了我提出的键入代码中的任何拼写错误。
编辑:我得到了答案
map.entrySet()
.stream()
.collect(Collectors.toMap(Map.Entry::getKey,
entry -> entry.getValue().stream().filter(predicate).collect(Collectors.toList())))
答案 0 :(得分:2)
我发现以下方法对我来说效果很好。欢迎任何更好的解决方案发布回复,并说明为何更好。目前,如果找不到匹配项,此代码将返回带有空列表的映射键(如果您有一个解决方案可以从结果中删除键,并且在没有匹配时返回null也会很好)。
map.entrySet()
.stream()
.collect(Collectors.toMap(Map.Entry::getKey,
entry -> entry.getValue()
.stream().filter(predicate)
.collect(Collectors.toList()))
)
答案 1 :(得分:0)
如果您不关心自己的初始地图,那么您可以使用以下代码段,该代码段会迭代存储在地图中的值,然后检查列表中的项目是否需要删除并没有完全填充谓词:
map.values().forEach(list -> list.removeIf(predicate.negate()));
我必须提到的是,这仅适用于可变列表。对于imutable,在运行时抛出未经检查的UnsupportedOperationException
。