Java 8 групповой список объектов со списком внутри - PullRequest
0 голосов
/ 02 октября 2018

В моем Java-проекте есть два объекта, которые выглядят примерно так:

FavoriteGroup
- int id
- string userId
- string name
- List<Favorite> favorites

и

Favorite
- int id
- int groupId
- string title
- string path

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

Более графическое объяснение: Я:

[{ 
    id: 1,
    userId: 1,
    name: "Group one",
    favorites: [{
       id: 100,
       groupId: 1,
       title: "Favorite 1",
       path: "path 1" 
    }]

 },
{ 
    id: 1,
    userId: 1,
    name: "Group one",
    favorites: [{
       id: 200,
       groupId: 1,
       title: "Favorite 2",
       path: "path 2" 
    }]

 },
{ 
    id: 2,
    userId: 1,
    name: "Group two",
    favorites: [{
       id: 300,
       groupId: 2,
       title: "Favorite 3",
       path: "path 3" 
    }]

 }]

И янужно:

[{ 
        id: 1,
        userId: 1,
        name: "Group one",
        favorites: [{
           id: 100,
           groupId: 1,
           title: "Favorite 1",
           path: "path 1" 
        },
       {
           id: 200,
           groupId: 1,
           title: "Favorite 2",
           path: "path 2" 
        }]

     },
    { 
        id: 2,
        userId: 1,
        name: "Group two",
        favorites: [{
           id: 300,
           groupId: 2,
           title: "Favorite 3",
           path: "path 3" 
        }]

     }]

Какой лучший способ сделать это?использовать для итераций цикла или, возможно, группировать функции потока Java 8?

Ответы [ 2 ]

0 голосов
/ 02 октября 2018

Я бы предпочел сделать это так,

private static final String DELIMITER = "-";

Map<String, List<Favorite>> favsByGroup = favGroups.stream()
       .collect(Collectors.groupingBy(g -> g.getId() + DELIMITER + g.getUserId() + DELIMITER + g.getName(),
            Collectors.flatMapping(fg -> fg.getFavorites().stream(), Collectors.toList())));
List<FavoriteGroup> mergedFavoriteGroups = favsByGroup.entrySet().stream()
    .map(e -> new FavoriteGroup(Integer.parseInt(e.getKey().split(DELIMITER)[0]),
        e.getKey().split(DELIMITER)[1], e.getKey().split(DELIMITER)[2], e.getValue()))
    .collect(Collectors.toList());

Сначала создайте карту, взяв в качестве ключа объединенные свойства Id, userId и name FavoriteGroup в качестве ключа и List из Favorite экземпляров.в качестве значения.Затем для каждой записи на карте я создам новый FavoriteGroup, расшифровав ключ и передав значения как есть.В качестве заключительного шага collect получаются объекты в контейнер.

0 голосов
/ 02 октября 2018

Попробуйте это: -

favoriteGroups.stream()
        .collect(Collectors.toMap(FavoriteGroup::getId, Function.identity(), (fg1, fg2) -> {
            //This will modify the original object(s). If you don't want that, then you'll have to clone the object and set favorites.
            fg1.setFavorites(Stream.concat(fg1.getFavorites().stream(), fg2.getFavorites().stream())
                    .collect(Collectors.toList()));
            return fg1;
        }))
        .values();

Это вернет объект типа Collection<FavoriteGroup>, который вы можете перебрать.Если вы хотите преобразовать его обратно в List, вы можете сделать List<FavoriteGroup> list = new ArrayList<>(favoriteGroupsCollection);.

...