Как преобразовать список вложенных объектов в список объектов с аналогичной информацией с помощью потоков

#java #data-structures #java-stream #collectors

Вопрос:

У меня есть этот список данных

 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
        }
    }
];
 

Я хочу, чтобы у меня был такой результат

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

Таким образом, группировка по статусу с соответствующими статусами.

Комментарии:

1. пожалуйста, добавьте код, который вы пробовали до сих пор, чтобы помочь вам лучше

2.У вас есть POJOs из Status MoreInfo SimilarInfo ? Если да, можете ли вы добавить их к своему вопросу?

3. из вопроса действительно ясно, какие атрибуты включены, мне нужно только сгруппировать их

4. @AlexAlex это объект JSON или java? или для тебя это не имеет значения?

5. Пожалуйста, добавьте полный код или удалите свой пост.

Ответ №1:

Вы можете сделать следующее:

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

Выход:

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

Если вас не устраивает карта, вы можете сделать это отсюда:

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

System.out.println(similarInfos);
 

Выход:

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

Комментарии:

1. Спасибо, возможно ли это сделать в одном методе?

2. @AlexAlex Ну, мы можем объединить два потока: ` List<SimilarInfo> similarInfos = statuses.stream() .collect(Коллекционеры.Группировка(Статус::getMainStatus, Коллекционеры.сопоставление(статус -<SimilarInfo>> статус.getMoreInfo().GetStatus(), Коллекционеры. ToList ()))). entrySet().поток() .карта(запись -> новая аналогичная информация(запись.getKey(), запись.GetValue ())). сбор(Сборщики. тоЛист());`