在 Java 8 中,如何将“平面”对象列表转换为嵌套对象列表?

In Java 8, how do I convert a List of "flat" objects into a List of nested objects?

提问人:Dave 提问时间:10/5/2023 最后编辑:NamanDave 更新时间:10/6/2023 访问量:53

问:

我正在使用 Java 8。我有一个java.util.List,其中包含这些“MyFlatObject”对象...

public class MyFlatObject {
    private String category;
    private String productId;
    private String feature;
    ...
}

如何将此列表转换为另一个 List of Category 对象,其中这些对象被定义为

public class Category {
    private String category;
    private List<Product> products;
    ...
}

public class Product {
    private String productId;
    private List<String> features;
    ...
}

?目标是,如果 List<MyFlatObject> 列表有 12 个对象,但只有 3 个不同的类别,则生成的 List<Category> 列表将只有三个对象,每个对象都有不同的 Category 对象,并且在每个 Category 对象中,所有相关产品。

嵌套 Java-Stream 收集器

评论

0赞 Dave 10/6/2023
我想看看,在Java 8的流和收集器功能下,是否有一种更流畅、更短的方法来做到这一点。

答:

0赞 Naman 10/5/2023 #1

您可能要查找的是使用 的下游函数。如果我做对了,您希望按多个属性进行分组并将它们转换为新对象,这很方便。Collectors.groupingByCollectors.mappingCollectors.collectingAndThen

假设这些类的 getter 和构造函数很少,则该方法可能类似于:

List<Category> categories = flatObjects.stream()
        .collect(Collectors.collectingAndThen(
                Collectors.groupingBy(MyFlatObject::getCategory,
                        Collectors.collectingAndThen(
                                Collectors.groupingBy(MyFlatObject::getProductId,
                                        Collectors.mapping(MyFlatObject::getFeature, Collectors.toList())),
                                val -> val.entrySet()
                                        .stream()
                                        .map(e -> new Product(e.getKey(), e.getValue()))
                                        .toList())),
                val -> val.entrySet().stream()
                        .map(e -> new Category(e.getKey(), e.getValue()))
                        .toList())
        );

评论

0赞 Dave 10/6/2023
“.toList()”似乎没有编译,但即使我替换了“.collect(Collectors.toList())”,我似乎也没有得到正确的结果。
0赞 Naman 10/6/2023
@Dave我已经分享了一种解决问题的方法,但鉴于您想要在何处执行它的示例和预期输出不太清楚,我将无法进一步添加详细信息。如果您遇到任何异常情况,请随时跟进更多详细信息。