【问题标题】:Java 8- Multiple Group by Into Map of CollectionJava 8- 多组按到集合映射中
【发布时间】:2015-10-29 21:40:23
【问题描述】:

我正在尝试对具有 Java 流的对象的两个属性执行 groupingBy。正如一些答案所记录的那样,这很容易:

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

比如上面的sn-p会产生一个Map of Maps的形式

Map<String, Map<String, List<Product>>>

其中映射具有 UPC 代码键,其值是具有引用产品列表的通道标识符键的映射。

这很酷,但是如果我不需要将嵌套值作为映射呢?也就是说,我想通过ChannelIdentifier来组织嵌套集合,但是我只关心map的.values(),而不关心map本身。有没有办法获得与以下匹配的结果?

Map<String, List<List<Product>>

列表或集合...没关系。谢谢!

【问题讨论】:

    标签: java-8 java-stream


    【解决方案1】:

    分组操作不可避免地需要维护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()) )));
    

    【讨论】:

    • 太棒了-谢谢!出于好奇,您是如何知道“collectingAndThen”的?您是否记住了 API 文档或者您有很好的资源?
    • 我通过回答 SO 问题和阅读其他人的 related answers 来记住 the API。培训是一个很好的副作用。
    猜你喜欢
    • 2019-02-10
    • 1970-01-01
    • 2018-01-03
    • 1970-01-01
    • 2018-12-22
    • 1970-01-01
    • 1970-01-01
    • 2014-01-10
    • 2018-03-30
    相关资源
    最近更新 更多