Java 8 Функция потоковой группировки на карту, где значением является карта - PullRequest
5 голосов
/ 30 января 2020

Я пытаюсь собрать результат списка и упорядочить их в карту, где значением является карта:

private Map<Organisation, Map<LocalDate, Status>> getSummaries(final List<Status> summaries) {
    return summaries
            .stream()
            .collect(groupingBy(Status::getOrganisation,
                    toMap(Status::getProcessedDate, Function.identity())));
}

Я получаю ошибку java.lang.IllegalStateException: Duplicate key, так как getProcessedDate() одинакова для разных значений в список.

Есть ли способ объединить несколько объектов с одинаковым processeddate в карту?

например, скажем, у меня есть эти объекты в списке:

Summary(ProcesseDate=2020-01-30, Organisation=ABC, status=OK, statusCount=5)
Summary(ProcesseDate=2020-01-30, Organisation=ABC, status=FAILED, statusCount=2)
Summary(ProcesseDate=2020-01-30, Organisation=APPLE, status=OK, statusCount=5)
Summary(ProcesseDate=2020-01-30, Organisation=APPLE, status=REJECTED, statusCount=5)

Значения, содержащиеся в карте, должны быть:

key=ABC
   value { key=2020-01-30, value= Summary(ProcesseDate=2020-01-30, Organisation=ABC, status=OK, statusCount=5), Summary(ProcesseDate=2020-01-30, Organisation=ABC, status=FAILED, statusCount=2) }

Когда я пытался toMap(Status::getProcessedDate, Function.identity(), (v1, v2) -> v2)));, он удаляет одну из записей

Ответы [ 2 ]

5 голосов
/ 30 января 2020

Возможно, вы просто ищете вложенную группу, если не хотите объединять данные и не имеете уникальных ключей:

private Map<Organisation, Map<LocalDate, List<Status>>> getSummaries(final List<Status> summaries) {
    return summaries
            .stream()
            .collect(groupingBy(Status::getOrganisation, groupingBy(Status::getProcessedDate)));
}
0 голосов
/ 30 января 2020

Если вы хотите объединить ключи, вы можете использовать Map.merge().

map.merge(key, value, bifunction);, чтобы проверить, присутствует ли key на карте. Если это не так, он вызывает map.put(key, value); Если это так, он применяет bifunction к существующему ключу и значению и сохраняет его на карте.

Например, если у вас есть Map<String, Integer>, это подсчитывает вхождения слова в отрывке, вы можете использовать следующее:

List<String> words = ...
Map<String, Integer> wordCount = ...

words.forEach(s -> wordCount.merge(s, 1, (word, count) -> count + 1));

Вы можете использовать это, чтобы не добавлять дубликаты ключей в ваш код.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...