Reputation: 275
Given that we have the following function:
public Map<String, List<String>> mapListIt(List<Map<String, String>> input) {
Map<String, List<String>> results = new HashMap<>();
List<String> things = Arrays.asList("foo", "bar", "baz");
for (String thing : things) {
results.put(thing, input.stream()
.map(element -> element.get("id"))
.collect(Collectors.toList()));
}
return results;
}
Is there some way I could clean this up by binding "id"
to a Map::get
method reference?
Is there a more stream-y way to write this functionality?
Upvotes: 2
Views: 1661
Reputation: 27986
As far as I can tell what you are intending is that this function returns a map from a defined list of strings to a list of all elements with key "id" in a list of input maps. Is that correct?
If so it could be significantly simplified as the value for all keys will be the same:
public Map<String, List<String>> weirdMapFunction(List<Map<String, String>> inputMaps) {
List<String> ids = inputMaps.stream()
.map(m -> m.get("id")).collect(Collectors.toList());
return Stream.of("foo", "bar", "baz")
.collect(Collectors.toMap(Function.identity(), s -> ids));
}
If you wish to use a method reference (which is my interpretation of your question about 'binding') then you will need a separate method to reference:
private String getId(Map<String, String> map) {
return map.get("id");
}
public Map<String, List<String>> weirdMapFunction(List<Map<String, String>> inputMaps) {
List<String> ids = inputMaps.stream()
.map(this::getId).collect(Collectors.toList());
return Stream.of("foo", "bar", "baz")
.collect(Collectors.toMap(Function.identity(), s -> ids));
}
However I'm guessing that you intended to use the items in the list as the keys (rather than "id") in which case:
public Map<String, List<String>> weirdMapFunction(List<Map<String, String>> inputMaps) {
return Stream.of("foo", "bar", "baz")
.collect(Collectors.toMap(Function.identity(), s -> inputMaps.stream()
.map(m -> m.get(s)).collect(Collectors.toList())));
}
Upvotes: 4