Я столкнулся с ошибкой в Java Streams. Я не могу разобраться сам.
Этот императивный код компилируется правильно:
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());
}
}
это, я думаю, должно быть таким же, но функционал не компилируется:
Map<Long, Integer> tempMap2 = changedFiltersChainsListSet.stream()
.map(f -> mariaEventService.getEventsUnderFilter(f).entrySet())
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
сообщенная проблема:
Type mismatch: cannot convert from Map<Object,Object> to Map<Long,Integer>
Почему Java во втором не может определить правильный тип?
РЕДАКТИРОВАТЬ
Чтобы лучше понять мой код, мой собственный метод getEventsUnderFilter(f)
возвращает 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
РЕШЕНИЕ
Как указывает WJS, ошибка здесь заключается в том, что в императивном коде есть два цикла, а в функциональном - только одна карта, рабочий код также выполняет итерацию к входному набору с помощью FlatMap:
Map<Long, Integer> tempMap2 = changedFiltersChainsListSet.stream()
.flatMap(f -> mariaEventService.getEventsUnderFilter(f).entrySet().stream())
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
Какую часть вы не можете понять? я сделаю их более ясными.
Похоже, что в вашей потоковой версии вы пропустили важный шаг.
В потоковом решении вы пытаетесь добавить entrySet()
на карту.
В императиве вы перебираете entrySet()
, захватываете значения записей и добавляете их на карту.
Таким образом, в потоковой версии вам необходимо flatMap
каждый entrySet
в поток, чтобы значения можно было извлечь из каждой записи.
Попробуйте следующее:
Map<Long, Integer> tempMap2 = changedFiltersChainsListSet.stream()
.flatMap(f -> mariaEventService.getEventsUnderFilter(f).stream())
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
да! вы правы, я пропустил второй цикл в своем потоке, но ваше объяснение указывает мне правильное направление. Если быть совсем точным, мне нужен getEventsUnderFilter(f).entrySet().stream() в вашем коде, вы пропустили входSet(). Спасибо за вашу помощь.
Вы дали код, который мы не можем расшифровать. минимальный воспроизводимый пример