Reputation: 2661
Map<Integer, String> map = new HashMap<>();
map.put(1, "f");
map.put(2, "I");
map.put(3, "a");
map.put(4, "c");....etc
Now I have a list:
List<Integer> picks = {1,3}
I would like to get back a list of Strings, ie, values from map that matches the key values, found in the 'pick' list.So, I am expecting to get back {"f", "a"} as result. Is there a way to use java stream api to do it in elegant way?
When there is one value , I am doing it this way:
map.entrySet().stream()
.filter(entry -> "a".equals(entry.getValue()))
.map(entry -> entry.getValue())
.collect(Collectors.toList())
But getting hard time when there is a list of keys/picks to filter with.
Upvotes: 9
Views: 5585
Reputation: 16908
You can use List.contains()
in the Stream#filter
to only accept those values which are present in the list:
List<String> result = map.entrySet()
.stream()
.filter(ent -> picks.contains(ent.getKey()))
.map(Map.Entry::getValue)
.collect(Collectors.toList());
Upvotes: 8
Reputation: 21124
You don't need to traverse the entire map just to collect picked values. Rather iterate over the required keys and grab the relevant values from the map. If the map is far more larger compared to the values you need to pick which is usually the case, then this approach should outperform the other. Moreover this solution is much more compact and has less visual clutter to me. Here's how it looks.
List<String> pickedValues = picks.stream().map(map::get)
.filter(Objects::nonNull)
.collect(Collectors.toList());
Upvotes: 5
Reputation: 16930
You can achieve this by using something like this :
List<String> values = map.entrySet()
.stream()
.filter(entry -> picks.contains(entry.getKey()))
.map(Map.Entry::getValue)
.collect(Collectors.toList());
values.forEach(System.out::println);
Output:
f
a
However it might not be efficient as List::contains
is O(N). Consider using a Set
(for example HashSet
) instead of List
for picks
as HashSet::contains
is O(1).
Upvotes: 8