4

I have the following Map:

HashMap<String, String> map1= new HashMap<String, String>();
map1.put("1", "One");
map1.put("2", "Two");
map1.put("3", "Three");

I have a list numbers which contains ["1","2","3"]

I have to perform the following operations:

List<String> spelling= new ArrayList<>();
for (String num: numbers) {
    if (map1.containsKey(num)){
        spelling.add(map1.get(num))
    }
}

How can I write the above code using lambda Expressions?

1
  • 3
    Downvoted for lack of attempt and prior research. I am sure there are zillion of similar questions around. Commented Jan 1, 2018 at 11:53

4 Answers 4

13

Use a Stream:

List<String> spelling = numbers.stream()
                               .map(map1::get)
                               .filter(Objects::nonNull)
                               .collect(Collectors.toList());
System.out.println (spelling);

Note that instead of checking if a key is in the map with containsKey, I just used get, and then filtered out the nulls.

Output:

[One, Two, Three]
Sign up to request clarification or add additional context in comments.

5 Comments

What is the use of .filter(Objects::nonNull) ? I mean map will return only those objects which matched the passed key..
@MehrajMalik If the key is not in the map, map1.get(k) will return null.
Ahh! I didn't notice that. +1 for .filter(Objects::nonNull)
Note that if map1 would possibly contain null values, this solution might give an unexpected result (depending on whether you want to retain those null values in the output)
@Ward Yes, if map1 contains null values and you wish to keep them in the output, you'll have to use .filter(k->map1.containsKey(k)).
5

A variant of Erans solution:

  1. Uses method references
  2. Uses containsKey instead of checking null values => if map1 would contain null values, checking null values would give a wrong result.

Code fragment:

List<String> spelling = numbers.stream()
        .filter(map1::containsKey)
        .map(map1::get)
        .collect(Collectors.toList());
System.out.println (spelling);

3 Comments

Don't like this, it calls Map.get twice. There is no reason to do this; Eran's answer is better.
Depends on the desired outcome: if you want to retain null values, using containsKey is simply the only way, and Erans answer will yield wrong results. Even if you don't want to retain null values, one could argue that the version with containsKey expresses more clearly the intention of the code.
That's fair - in the case where that is the desired outcome then containsKey is required. But I'm not sure that the intent argument is valid - I would argume that the intent is clear either way but that using containsKey has double the overhead of the null check.
2

another option would be to use the forEach construct:

numbers.forEach(n -> { 
       if(map1.containsKey(n))
           spelling.add(map1.get(n));
});

3 Comments

Not sure this really adds anything over a normal foreach loop, besides complexity. I dislike these uses of forEach.
@BoristheSpider agreed that it doesn't add anything over a normal foreach loop . However, it's just that OP wanted to use "lambda" and hence the suggestion.
Yeah, understood - just wanted to say that this isn't really idomatic Java 8; more just using lambdas for the sake of it. Not convinced it's really useful, but it isn't wrong or harmful, so just a comment.
1

Try like this

 List<String> spelling = map1.keySet().stream()
                    .filter(numbers::contains)
                    .map(map1::get)
                    .collect(Collectors.toList());

2 Comments

Very inefficient compared to the other answers. You have provided an O(n*m) solution (n is map1.size(), m is numbers.size()) rather than an O(m) solution.
Also, the order of result list may not correspond to the numbers list, as HashMap has no guaranteed iteration order.

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.