Преобразование карты в Java с использованием Java 8 потоков - разделение карты на основе значения карты - PullRequest
0 голосов
/ 17 апреля 2020

У меня есть карта в Java:

Map<String, Set<EntityObject>> itemGroupsMap

class EntityObject {
  boolean isParent;
  String groupId;
}

Теперь я хочу преобразовать itemGroupsMap Map --- в ---:

Map<EntityObject, Set<EntityObject>> parentChildMap.

Лог c состоит в том, что каждая запись itemGroupsMap -> Set -> Среди этого набора будет EntityObject, который будет родительским (EntityObject.isParent = 1). Таким образом, для каждой записи в карте мне нужно найти родительский объект EntityObject и сделать его ключом parentChildMap и поместить только оставшиеся полномочия в качестве Set / List для этого ключа.

Я пытался использовать 2 цикла foreach, и я довольно плохо знаком с Java 8, поэтому искал, как я могу уменьшить свой код с помощью потоков?

Я посмотрел на Collectors.partitioningBy, но он создает 2 карты с 0, 1 ключом. Мне это действительно не нужно.

Есть предложения?

Ответы [ 2 ]

0 голосов
/ 17 апреля 2020

Вот несколько подходов, если я понимаю, что вы хотите. Если ключ карты - EntityObject, то он должен переопределить equals, чтобы позаботиться о дублирующих ключах, которые не разрешены. Это можно сделать, используя Id как часть реализации equals (что не очевидно из представленного класса)

            Map<EntityObject, Set<EntityObject>> parentChildMap =
                itemGroupsMap.entrySet().stream()
                        .collect(Collectors.toMap(
                                // get the single parent object and use
                                // as a key
                                e -> e.getValue().stream()
                                        .filter(o -> o.isParent)
                                        .findFirst().get(),
                                // get the value and remove the parent
                                // key, convert to a set and use as the new
                                // value.
                                e -> e.getValue().stream()
                                        .filter(o -> !o.isParent)
                                        .collect(
                                                Collectors.toSet())));

Возможно, есть лучший способ сделать это с потоками, но я предпочитаю следующее как это прямо вперед.

        // create the map
        Map<EntityObject, Set<EntityObject>> parentChildMap = new HashMap<>();

        for (Entry<String, Set<EntityObject>> e : itemGroupsMap
                .entrySet()) {

            // get the set of EntityObjects
            Set<EntityObject> eoSet = e.getValue();

            // get the parent one
            EntityObject parentObject = eoSet.stream()
                    .filter(eo->eo.isParent).findFirst().get();

            // remove the parent one from the set
            eoSet.remove(parentObject);

            // add the parentObject and the set to the map
            parentChildMap.put(parentObject,eoSet);
        }
0 голосов
/ 17 апреля 2020

Может быть что-то вроде этого:

Map<EntityObject, Set<EntityObject>> newMap = itemGroupsMap.entrySet().stream()
        .collect(Collectors.toMap(
                entry -> entry.getValue().stream().filter(value -> value.isParent).findFirst().orElse(null),
                Map.Entry::getValue
        ));

Note: его код не заботится о наборе данных в исходной карте без родителя -> entry.getValue().stream().filter(value -> value.isParent).findFirst().orElse(null), он говорит: set null как ключ, когда нет родителей в наборе. Таким образом, если это возможно, то каждый набор без родителя будет перезаписан следующим набором без родителя.

...