将Java 8 Stream函数分组到Map,其中值是Map

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了将Java 8 Stream函数分组到Map,其中值是Map相关的知识,希望对你有一定的参考价值。

我正在尝试收集列表的结果并将它们组织到一个值是Map的Map中:

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)));时,它会删除其中一个条目

答案

如果要合并键,则可以使用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));

您可以使用它来避免在代码中添加重复的键。

另一答案

如果您不想合并数据并且没有唯一键,您可能只是在寻找嵌套的分组:

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

以上是关于将Java 8 Stream函数分组到Map,其中值是Map的主要内容,如果未能解决你的问题,请参考以下文章

Java 8 流:列表到按 [重复] 分组的平面地图

Java 8 - 在 stream.map() 中链接构造函数调用和设置器

Java 8 Map & Stream - 按值 desc 和组排序

Java 遍历Map;Stream 对列表分组的groupBy

Java 遍历Map;Stream 对列表分组的groupBy

Java 遍历Map;Stream 对列表分组的groupBy