java-8 - Java 8- Multiple Group by进入集合映射

标签 java-8 java-stream

我正在尝试通过对带有Java流的对象的两个属性进行分组。正如一些答案所记录的那样,这很容易:

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

例如,上面的代码片段将生成以下形式的Maps
Map<String, Map<String, List<Product>>>

映射具有UPC代码的键,并且其值是具有 channel 标识符的键的映射,该 channel 标识符引用了产品列表。

太酷了,但是如果我不需要嵌套值成为 map 怎么办?也就是说,我想通过ChannelIdentifier来组织嵌套的集合,但是我只关心 map 的.values(),而不关心 map 本身。有没有一种方法可以得到与以下结果匹配的结果?
Map<String, List<List<Product>>

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

最佳答案

分组操作不可避免地需要维护Map,因为它必须跟踪分组的键值。但是您可以直接使用values() View :

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

如果生成的 map 的生命周期更长,并且您想减少所需的存储空间,或者如果需要List,则可以在该步骤中将 View 复制到列表中:
Map<String, List<List<Product>>> map=products.stream().collect(
    Collectors.groupingBy(Product::getUpc, Collectors.collectingAndThen(
        Collectors.groupingBy(Product::getChannelIdentifier),
        m -> new ArrayList<>(m.values()) )));

关于java-8 - Java 8- Multiple Group by进入集合映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33425107/

相关文章:

java - 如何将前端(C#、HTML、JQuery)与后端(JAX-RS(Jersey)和JAVA)进行通信?

lambda - Java 8 - 在 List 中存储 lambdas

java - 根据另一个列表 Java 对列表进行排序

java - 如何使用无限的java.util.stream.Stream?

java - 使用比较器对 VO 的嵌套列表进行排序

intellij-idea - Lombok @RequiredArgsConstructor(onConstructor_ = {@MyAnnotation}) IntelliJ IDEA 编译错误

java - 在 Java 8 中迭代 map 时使用 ForEach 提取多行 Lambda 表达式

java Streams - 如何将一个集合过滤为两个新集合

java - 平面化 n 阶树结构 : Java Streams

java - Java 8 Stream 中有多个正则表达式从 Line 读取文本