首页 > 解决方案 > Java收集返回顶级项目的嵌套地图流

问题描述

我有以下模型:

class Item {
    String name;
    ...
    List<SubItem> subItems;
}

class SubItem {
    String name;
    ...
    List<String> ids;
}

对于每一个idsubItem.ids想提取一些顶级参数。为此,我定义了一个自定义元组:

class AdditionalParams {
    private final String itemName;
    private final String subItemName;
    ...
}

目标是返回一个Map<String, AdditionalParams>where:

我假设 id 是唯一的,因此在向 Map 添加元素时不会有任何冲突。

我的解决方案

我尝试使用flatMapwith Collectors.toMap

List<Item> allItems = ...
Map<String, AdditionalParams> result = allItems
    .stream()
    .flatMap(i -> i.getSubItems()
                   .stream()
                   .map(si -> si.getIds()
                                .stream()
                                .collect(
                                    Collectors.toMap(
                                        Function.identity(),
                                        id -> new AdditionalParams(i.getName(), si.getName())
                                    )
                                )
                   )
    )  // Stream< Map<String, AdditionalParams> >
    .collect(
        Collectors.toMap(m -> m.getKey(), m -> m.getValue())
    )

问题是最后一行 ( .collect(Collectors.toMap(...) 不起作用(或者我做错了)。我试图按照这个答案将地图列表通过流转换为单个地图,但也无法使其工作。

我的方法做错了什么?我怎样才能得到类型的结果Map<String, AdditionalParams>

标签: javajava-streamcollectors

解决方案


您可以做些什么来解决这个问题,将中间状态映射到映射的条目,然后收集它们。这会像 -

Map<String, AdditionalParams> result = allItems
        .stream()
        .flatMap(item -> item.getSubItems().stream()
                .flatMap(subItem -> subItem.getIds()
                        .stream()
                        .map(id -> new AbstractMap.SimpleEntry<>(
                                id, new AdditionalParams(item.getName(),
                                subItem.getName())))))
        .collect(Collectors.toMap(AbstractMap.SimpleEntry::getKey,
                AbstractMap.SimpleEntry::getValue));

推荐阅读