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

时间:2019-08-21 18:39:35

标签: java lambda java-8 java-stream collectors

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}

我想取回一个字符串列表,即映射中与“ pick”列表中的键值匹配的值。因此,我希望取回{“ f”,“结果” 。有没有一种方法可以使用 java流api 轻松地做到这一点?

当有一个值时,我就是这样:

map.entrySet().stream()
            .filter(entry -> "a".equals(entry.getValue()))
            .map(entry -> entry.getValue())
            .collect(Collectors.toList())

但是当有一系列要过滤的键/小节使用时,会变得很困难。

3 个答案:

答案 0 :(得分:7)

您可以通过使用类似这样的方法来实现:

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)可能不太有效。考虑为List使用Set(例如HashSet)(例如picks),因为HashSet::contains为O(1)。

答案 1 :(得分:6)

您可以在List.contains()中使用Stream#filter仅接受列表中存在的那些值:

List<String> result = map.entrySet()
                         .stream()
                         .filter(ent -> picks.contains(ent.getKey()))
                         .map(Map.Entry::getValue)     
                         .collect(Collectors.toList());

答案 2 :(得分:6)

您无需遍历整个地图即可收集选择的值。而是遍历所需的键并从映射中获取相关值。如果通常情况下地图与您需要选择的值相比要大得多,则此方法应优于其他方法。而且,此解决方案更紧凑,对我而言,视觉上的混乱也更少。看起来就是这样。

List<String> pickedValues = picks.stream().map(map::get)
    .filter(Objects::nonNull)
    .collect(Collectors.toList());