Reputation: 67
I have a particular problem and was wondering whether the Java 8 Streams API could solve it. I know that this can be done outside of using Streams API but I don't want to add all the boilerplate code associated with trying to achieve that, if it can be done using Streams. I have a map
Map<String, String> greetings = new HashMap<>();
greetings.put("abc", "Hello");
greetings.put("def", "Goodbye");
greetings.put("ghi", "Ciao");
greetings.put("xyz", "Bonsoir");
and a list of keys:
List<String> keys = Arrays.asList("def", "zxy");
and using the above with Streams API, is it possible to filter that down to:
Map<String, String> filteredGreetings = new HashMap<>();
filteredGreetings.put("def", "Goodbye");
filteredGreetings.put("xyz", "Bonsoir");
Hopefully this makes sense what I am trying to achieve.
So far I have got this to work only when specifying the exact key which to filter the map's keySet on, but then this would only return a single entry set. I am interested in a completely filtered down map and I am struggling to achieve that.
Upvotes: 4
Views: 664
Reputation: 31878
If the input and the expected output in the question is not a typo, you can also retain the keys of the input map as:
Map<String, String> futureGreetings = new HashMap<>(greetings);
futureGreetings.keySet().retainAll(keys);
Upvotes: 4
Reputation: 11042
Try this:
Map<String, String> result = keys.stream()
.filter(greetings::containsKey)
.collect(Collectors.toMap(Function.identity(), greetings::get));
Or the other way round:
Map<String, String> result = greetings.entrySet().stream()
.filter(e -> keys.contains(e.getKey()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
For the second approach I would recommend using a Set<String>
for a larger list of keys
because it has a O(1) time complexity for .contains()
because it does not contain any duplicates:
Set<String> keys = new HashSet<>(Arrays.asList("def", "zxy"));
Upvotes: 3
Reputation: 17289
Try this
filteredGreetings= keys.stream()
.collect(Collectors.toMap(Function.identity(),key->greetings.get(key)));
or even for absent key you can use getOrDefault()
method.
... .collect(Collectors.toMap(Function.identity(),key->greetings.getOrDefault(key,"")));
Upvotes: 0