9
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.

3 Answers 3

8

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());
Sign up to request clarification or add additional context in comments.

Comments

8

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).

Comments

5

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());

1 Comment

This is a very good solution. However you should also filter out null values after map operation as Map::get() will return null for non existing keys in the map for values from picks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.