[英]How to filter a map with Java stream api?
Map<Integer, String> map = new HashMap<>();
map.put(1, "f");
map.put(2, "I");
map.put(3, "a");
map.put(4, "c");....etc
现在我有一个清单:
List<Integer> picks = {1,3}
我想取回字符串列表,即匹配键值的地图中的值,在“选择”列表中找到。所以,我希望返回 {"f", "a"} 作为结果。 有没有办法使用java流api以优雅的方式做到这一点?
当有一个 value 时,我这样做:
map.entrySet().stream()
.filter(entry -> "a".equals(entry.getValue()))
.map(entry -> entry.getValue())
.collect(Collectors.toList())
但是当有要过滤的键/选择列表时会变得困难。
你可以通过使用这样的东西来实现这一点:
List<String> values = map.entrySet()
.stream()
.filter(entry -> picks.contains(entry.getKey()))
.map(Map.Entry::getValue)
.collect(Collectors.toList());
values.forEach(System.out::println);
输出:
f
a
但是它可能效率不高,因为List::contains
是 O(N)。 考虑使用Set
(例如HashSet
)而不是List
进行picks
因为HashSet::contains
是 O(1)。
您可以在Stream#filter
使用List.contains()
来仅接受列表中存在的那些值:
List<String> result = map.entrySet()
.stream()
.filter(ent -> picks.contains(ent.getKey()))
.map(Map.Entry::getValue)
.collect(Collectors.toList());
您不需要遍历整个地图来收集选取的值。 而是迭代所需的键并从地图中获取相关值。 如果地图比通常情况下您需要选择的值大得多,那么这种方法应该优于另一种方法。 此外,这个解决方案更紧凑,对我来说视觉混乱更少。 这是它的外观。
List<String> pickedValues = picks.stream().map(map::get)
.filter(Objects::nonNull)
.collect(Collectors.toList());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.