Search code examples
javadata-structuresjava-streamcollectors

How to convert list of nested object to list of objects with similar informations using streams


I have this list of data

List<Status> statuses = [
    {
        id: 123
        mainSatus: HA
        MoreInfo: {
            name: max
            status: MM
        }
    },
    {
        id: 456
        mainSatus: HA
        MoreInfo: {
            name: max
            status: KK
        }
    },
    {
        id: 777
        mainSatus: OU
        MoreInfo: {
            name: max
            status: KK
        }
    }
];

I want to have an output like this

List<SimilarInfo> similarinfos = [{mainStatus:HA, statueses:[MM,KK]} , {mainStatus:OU, statuses:[KK]}];

So grouping by mainStatus with corresponding statuses.


Solution

  • You can do the following:

    List<Status> statuses = Arrays.asList(
            new Status(123, "HA", new MoreInfo("max", "MM")),
            new Status(456, "HA", new MoreInfo("max", "KK")),
            new Status(777, "OU", new MoreInfo("max", "KK"))
    );
    
    Map<String, List<String>> mainStatusToStatuses = statuses.stream()
            .collect(Collectors.groupingBy(Status::getMainStatus,
                    Collectors.mapping(status -> status.getMoreInfo().getStatus(), Collectors.toList())));
    
    System.out.println(mainStatusToStatuses);
    

    Output:

    {OU=[KK], HA=[MM, KK]}
    

    If you are not satisfied with the map, you can do from here:

    List<SimilarInfo> similarInfos = mainStatusToStatuses.entrySet().stream()
            .map(entry -> new SimilarInfo(entry.getKey(), entry.getValue()))
            .collect(Collectors.toList());
    
    System.out.println(similarInfos);
    

    Output:

    [SimilarInfo(mainStatus=OU, statuses=[KK]), SimilarInfo(mainStatus=HA, statuses=[MM, KK])]