0

How can I write the logic to obtain a Map<String, Map<String, String>> using streams?

Here is the code I have tried :

public Map<String, Map<String, String>> getData(Set<String> Ids) {
    List<Events> events = repository.findAllByIdIn(Ids);

    int i = 0;
    return events.stream()
            .sorted(Comparator.comparing(Events::getMajor).thenComparing(Events::getMinor))
            .collect(Collectors.groupingBy(Events::getId, 
    //Error-Cannot resolve method 'getMajor()'
    Collectors.mapping(cae -> cae.getMajor() + "." + cae.getMinor(), 
        cae.getDates().get(i).getEndDate() != null ? "Predicted" : "Not Predicted"), 
             Collectors.toMap())));//Error-Cannot resolve method 'toMap()'
}

So how do I loop through a map inside another map?

2
  • the second argument to groupingBy must be a Collector, but you provided a Function Commented Apr 26, 2022 at 9:09
  • hi @Lino, I have provided the argument but it still gives an error. What other way could I write this in? Commented Apr 26, 2022 at 9:21

1 Answer 1

1

Collector toMap() contrary to collectors toList() and toSet() isn't parameterless, you need to provide information how a key and a value should be extracted from a single stream element.

Collectors.toMap() expects at least two functions: keyMapper and valueMapper. In case if there could be duplicates, you need to use the flavor of toMap which takes a mergeFunction as a third argument to resolve the values that collide on the same key.

So you need to place toMap() as a second argument (downstream collector) into the groupingBy. That will be a syntactically correct structure of the collectors and functions:

Collectors.groupingBy(classifier, Collectors.toMap(keyMapper, valueMapper))

And that how the code might look like:

return events.stream()
        .sorted(Comparator.comparing(Events::getMajor)
            .thenComparing(Events::getMinor))
        .collect(Collectors.groupingBy(Events::getId,
            Collectors.toMap(cae -> cae.getMajor() + "." + cae.getMinor(),
                cae -> cae.getDates().get(i).getEndDate() != null ? 
                    "Predicted" : "Not Predicted")));

Note, Collectors.mapping() isn't meant to produce a Map but to transform the elements of the stream, you can think of it as an analog of the map() operation that is done not is the middle of the stream pipeline, but during the process of collecting the data.

And if I understood your logic correctly, there's no need to apply mapping() here.

Sign up to request clarification or add additional context in comments.

Comments

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.