javajava-stream

Type mismatch: cannot convert from Map<Object,Object> to Map<Long,Integer> using EntrySet


I am facing an error with java Streams I can't figure it out by myself.

This imperative code compile correctly:

Map<Long, Integer> tempMap = new HashMap<>();
for (FiltersDataChain filtersDataChain : changedFiltersChainsListSet) {
    for (Entry<Long, Integer> entry : mariaEventService.getEventsUnderFilter(filtersDataChain).entrySet()) {
        tempMap.putIfAbsent(entry.getKey(), entry.getValue());
    }
}

this, which I think should be the same but functional doesn't compile:

Map<Long, Integer> tempMap2 = changedFiltersChainsListSet.stream()
                            .map(f -> mariaEventService.getEventsUnderFilter(f).entrySet())
                            .collect(Collectors.toMap(Entry::getKey, Entry::getValue));

the problem reported is:

Type mismatch: cannot convert from Map<Object,Object> to Map<Long,Integer>

Why java in the second one can't infer the correct Type?

EDIT

To better understand my code my custom method getEventsUnderFilter(f) return a Map<Long, Integer>:

Map<Long, Integer> it.fox.hermes.services.MariaEventService.getEventsUnderFilter(FiltersDataChain filtersDataChain)
Return the list of events this filter is used for

Parameters: filtersDataChain the filter to analyse
Returns: the Map of Event Id and msn found

SOLUTION

As pointed by WJS the error here is that in the imperative code there are two loops but in the functional one there is just one map, the working code iterate to the entrySet too with a flatMap:

Map<Long, Integer> tempMap2 = changedFiltersChainsListSet.stream()
                            .flatMap(f -> mariaEventService.getEventsUnderFilter(f).entrySet().stream())
                            .collect(Collectors.toMap(Entry::getKey, Entry::getValue));

Solution

  • It appears that in your stream version you omitted a crucial step.

    In the stream solution you are trying to add the entrySet() to the map.

    In the imperative you iterate over the entrySet() and grab the entry values and add them to the map.

    So in the stream version you need to flatMap each entrySet onto the stream so that the values can be extracted from each entry.

    Try the following:

    Map<Long, Integer> tempMap2 = changedFiltersChainsListSet.stream()
        .flatMap(f -> mariaEventService.getEventsUnderFilter(f).entrySet().stream())
        .collect(Collectors.toMap(Entry::getKey, Entry::getValue));