繁体   English   中英

如何使用 Java 流 api 过滤地图?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM