Java 8- 将多个分组依据转换为集合映射

6

我试图使用Java流对对象的两个属性进行groupingBy,这可以通过一些答案的记录很容易地实现:

products.stream().collect(
        Collectors.groupingBy(Product::getUpc, 
        Collectors.groupingBy(Product::getChannelIdentifier)));

例如,上面的代码片段将生成一个形式为“Map of Maps”的映射。
Map<String, Map<String, List<Product>>>

一个地图的键是UPC码,它的值是一些有渠道标识符作为键的地图,这些地图引用了产品列表。

很酷,但如果我不需要嵌套的值是一个地图呢?也就是说,我想通过ChannelIdentifier组织嵌套集合,但我只关心地图的.values(),而不是地图本身。有没有办法得到与以下匹配的结果?

Map<String, List<List<Product>>

无论是列表还是集合...都没关系。谢谢!

1个回答

14

由于分组操作必须跟踪分组的键值,因此不可避免地需要维护一个 Map。但是您可以直接使用 values() 视图:

Map<String, Collection<List<Product>>> m=products.stream().collect(
    Collectors.groupingBy(Product::getUpc, Collectors.collectingAndThen(
        Collectors.groupingBy(Product::getChannelIdentifier), Map::values)));

如果生成的地图将拥有更长的生命周期并且您想要减少所需的存储空间,或者如果您需要一个List,则可以在该步骤中将视图复制到列表中:

Map<String, List<List<Product>>> map=products.stream().collect(
    Collectors.groupingBy(Product::getUpc, Collectors.collectingAndThen(
        Collectors.groupingBy(Product::getChannelIdentifier),
        m -> new ArrayList<>(m.values()) )));

1
太棒了-谢谢!出于好奇,你是怎么知道“collectingAndThen”的?你是记住了API文档还是有一个好的资源可以查阅? - IcedDante
7
我通过回答堆栈溢出网站上的问题和阅读他人的相关答案来记忆API,这种训练是一个不错的副作用。 - Holger

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接