java 8 - 从地图中过滤值列表的方法?

时间:2018-02-17 00:18:37

标签: lambda java-8 java-stream

我有一张地图

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())))

2 个答案:

答案 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

  

文档: Collection.removeIf(Predicate)