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.
The map() will then return a Stream of Integer which contains both even and odd numbers. To select just even numbers, we can use the filter() method. It takes a predicate object which is technically a function to convert an object to a boolean. We pass an object and it will return true or false.
Step 1 Go to Add/Manage Map -> Edit Page. Step 2 Assign those Locations using Choose Locations section, which you want to display on a google maps. Step 3 Scroll down to Custom Filters and insert placeholders like {country},{state},{city}. Insert Filter text according to it Filter placeholder.
Once we have the Stream of Integer, we can apply maths to find the even numbers. We passed that condition to filter method. If we needed to filter on String, e.g. select all string which has length > 2, then we would have called filter before map. That's all about how to use map and filter in Java 8.
Converting only the Value of the Map<Key, Value> into Stream: This can be done with the help of Map. values() method which returns a Set view of the values contained in this map. In Java 8, this returned set can be easily converted into a Stream of key-value pairs using Set. stream() method.
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());
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).
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());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With