Tony Ghita
Tony Ghita

Reputation: 275

Java 8 Streams — Mapping maps

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

Answers (1)

sprinter
sprinter

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

Related Questions