Using Streams filter Map based on a list of keys

Richard C :

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.

Samuel Philipp :

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

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=121655&siteId=1