如何使用 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}
我想取回一个字符串列表,即映射中与键值匹配的值,在 'pick' list.So 中找到,我期待返回 {"f", "a"} 作为结果。有没有办法使用 java 流 api 以优雅的方式做到这一点?
当有一个值时,我是这样做的:
map.entrySet().stream()
.filter(entry -> "a".equals(entry.getValue()))
.map(entry -> entry.getValue())
.collect(Collectors.toList())
但是当有 keys/picks 的列表可供过滤时,会遇到困难。
您可以使用类似这样的方法实现此目的:
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)。考虑对 picks
使用 Set
(for example HashSet
) 而不是 List
因为 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());
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' list.So 中找到,我期待返回 {"f", "a"} 作为结果。有没有办法使用 java 流 api 以优雅的方式做到这一点?
当有一个值时,我是这样做的:
map.entrySet().stream()
.filter(entry -> "a".equals(entry.getValue()))
.map(entry -> entry.getValue())
.collect(Collectors.toList())
但是当有 keys/picks 的列表可供过滤时,会遇到困难。
您可以使用类似这样的方法实现此目的:
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)。考虑对 picks
使用 Set
(for example HashSet
) 而不是 List
因为 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());