当前位置: 首页 > 知识库问答 >
问题:

Java 8嵌套(多级)组由

匡安宜
2023-03-14

我很少有像下面这样的课

class Pojo {
    List<Item> items;
}

class Item {
    T key1;
    List<SubItem> subItems;
}

class SubItem {
    V key2;
    Object otherAttribute1;
}

我希望根据key1聚合项,对于每一个聚合,子项都应该通过key2以以下方式聚合:

Map<T, Map<V, List<Subitem>>
pojo.getItems()
    .stream()
    .collect(
        Collectors.groupingBy(Item::getKey1, /* How to group by here SubItem::getKey2*/)
    );

共有1个答案

云俊名
2023-03-14

不能通过多个键对单个项进行分组,除非您接受该项可能出现在多个组中。在这种情况下,您需要执行一种FlatMap操作。

实现这一点的一种方法是在收集之前使用stream.flatmap和一个临时对,其中包含itemsubitem的组合。由于没有标准的对类型,典型的解决方案是使用map.entry:

Map<T, Map<V, List<SubItem>>> result = pojo.getItems().stream()
    .flatMap(item -> item.subItems.stream()
        .map(sub -> new AbstractMap.SimpleImmutableEntry<>(item.getKey1(), sub)))
    .collect(Collectors.groupingBy(AbstractMap.SimpleImmutableEntry::getKey,
                Collectors.mapping(Map.Entry::getValue,
                    Collectors.groupingBy(SubItem::getKey2))));

另一种不需要这些临时对象的方法是在收集器中执行flatmap操作,但不幸的是,flatmapp直到Java ;9才会出现。

Map<T, Map<V, List<SubItem>>> result = pojo.getItems().stream()
    .collect(Collectors.groupingBy(Item::getKey1,
                Collectors.flatMapping(item -> item.getSubItems().stream(),
                    Collectors.groupingBy(SubItem::getKey2))));

如果我们不想等待Java9,我们可以在代码库中添加一个类似的收集器,因为它并不难实现:

static <T,U,A,R> Collector<T,?,R> flatMapping(
    Function<? super T,? extends Stream<? extends U>> mapper,
    Collector<? super U,A,R> downstream) {

    BiConsumer<A, ? super U> acc = downstream.accumulator();
    return Collector.of(downstream.supplier(),
        (a, t) -> { try(Stream<? extends U> s=mapper.apply(t)) {
            if(s!=null) s.forEachOrdered(u -> acc.accept(a, u));
        }},
        downstream.combiner(), downstream.finisher(),
        downstream.characteristics().toArray(new Collector.Characteristics[0]));
}
 类似资料:
  • 问题内容: 我正在尝试将JSON转换为CSV文件,可用于进一步分析。我的结构存在的问题是,当我转换JSON文件时,我有很多嵌套的字典/列表。 我尝试使用pandas ,但它只会使第一级扁平化。 任何想法如何讨好整个JSON文件,以便我可以为单个(在本例中为虚拟机)条目创建到CSV文件的单行输入?我已经尝试过这里发布的几种解决方案,但是我的结果始终只是将第一级展平。 这是示例JSON(在这种情况下,

  • 我得到了一个类似于elasticsearch文档多级嵌套查询示例中显示的示例索引的索引:https://www . elastic . co/guide/en/elastic search/reference/current/query-DSL-nested-query . html # multi-level-nested-query-ex 给定这些示例文档: 我需要能够找到司机的文件。make

  • 我尝试在两个列表上循环,过滤嵌套列表,并使用java8特性将结果写回主对象。 因此,到目前为止,位置内部的子列表不会更改,这是显而易见的,因为流和收集确实会创建一个新列表,该列表不会写回位置对象中。所以我的问题是,如果有一种方法可以调用位置对象的setSubList(...)方法并将新列表写入其中。 感谢

  • 我试图弄清楚嵌套for循环是如何与JavaScipt中的多维数组一起工作的,但有一点让我有些困惑。以股票为例 这就是我所期望的结果123456。但是,如果我将数字添加到外部数组的末尾: 我仍然得到同样的输出1 2 3 4 5 6?我不明白为什么 输出是一个bcdyz,这是我所期望的。为什么字符串的行为会有所不同?

  • 问题内容: MYSQL返回一个数组,如下所示。我正在使用列:“ id_parent”自引用表以创建层次结构。因此,“ id”为2的条目可以是“ id_parent”为2的任何条目的父级,依此类推。 如何将子级嵌套在其父级数组中的数组中 问题答案: 引用具有顺序无关紧要的优点(子节点可以位于其父节点之前):

  • 问题内容: 我有一个从数据库(JSON MySQL中的数据存储)检索数据的程序。 我设法得到对象。输出为: JSON对象: 我需要有关如何处理数据并将信息放入不同数组/对象的建议。例如 谢谢。 问题答案: 您可以使用Jackson Api来实现。 您必须创建与json对象相同的Pojo类(该类应具有“ attributes”,“ uuid”之类的成员)。 这是您必须使用的类 和代码 现在,您可以使