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

151 Views Asked by At

I'm using Java 8. I have a java.util.List of these "MyFlatObject" objects ...

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

How would I convert this List into another List of Category objects, in which those are defined as

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

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

? The goal being that if the List<MyFlatObject> list has 12 objects, but only 3 distinct categories, my resulting List<Category> list would only have three objects, each with the distinct Category object and within each Category object, all the relevant products.

1

There are 1 best solutions below

2
Naman On

What you are possibly looking for would be Collectors.groupingBy with a downstream function using Collectors.mapping. If I get it right you are looking to group by multiple attributes and transform them into new objects which is where Collectors.collectingAndThen could be handy.

Assuming few getters and constructors over these classes, the approach could be similar to:

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())
        );