Есть ли способ получить список всех последующих дочерних элементов данного родителя с карты?


    public static Map<String, List<String>> childParentMap = new HashMap<>();


    public static List<String> immediateParents(String key) {
        return childParentMap.get(key);
    }

    public static List<String> getAllParents(String key, List<String> allParents) {

        List<String> immediateParents = childParentMap.get(key);

        if (immediateParents == null || immediateParents.isEmpty()) {
            return new ArrayList<>();
        }
        for (String parent : immediateParents) {

            List<String> list = getAllParents(parent, allParents);
            allParents.addAll(list);
            allParents.add(parent);

        }
        allParents.add(key);
        return allParents;

    }


    public static void main(String[] args) {
        System.out.println("helloo world");
        childParentMap.put("fc", Arrays.asList("x", "y"));
        childParentMap.put("x", Arrays.asList("m", "n"));

        String key = "fc";  // get all parents of fc child.
        List<String> res = getAllParents(key, new ArrayList<>());
        System.out.println(res);


    }
}

Здесь для данного ключа (скажем, родительского "fc") я хочу получить все его значения (скажем, дочерние элементы, которые будут x,y,m и n). Причина в том, что у fc есть дети x и y, но у x также есть дети m и n. так что для ФК все иерархические дочерние элементы будут x,y,m и n.

Я попробовал, но при запуске приведенного выше кода я также получаю дубликаты, я пытался отладить, но не смог его получить. Вот что я получаю на выходе [m, n, x, m, n, x, x, y, fc], которые имеют дубликаты.

Я пробовал писать код с рекурсией, но выходные данные, похоже, имеют дубликаты. Хотя правильный результат должен быть [m, n, x, y];

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
78
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;

public class Example {

    public static Map<String, List<String>> childParentMap = new HashMap<>();

    public static void main(String[] args) {

        childParentMap.put("fc", Arrays.asList("x", "y"));
        childParentMap.put("x", Arrays.asList("m", "n"));

        String key = "fc";  // get all parents of fc child.
        List<String> res = getAllParentsStream(key);
        System.out.println(res);

        List<String> res2 = getAllParentsForLoop(key);
        System.out.println(res2);

    }

    public static List<String> getAllParentsForLoop(String key) {
        List<String> parents = new ArrayList<>();
        if (childParentMap.containsKey(key)) {
            List<String> directParents = childParentMap.get(key);
            parents.addAll(directParents);

            for (String parent : directParents) {
                if (childParentMap.containsKey(parent)) {
                    parents.addAll(getAllParentsForLoop(parent));
                }
            }
        }
        return parents;
    }

    public static List<String> getAllParentsStream(String key) {
        return Stream.concat(
                             childParentMap.get(key).stream(),
                             childParentMap.get(key).stream()
                                           .flatMap(ch -> childParentMap.containsKey(ch) ? 
                                                          getAllParentsStream(ch).stream() : 
                                                          Stream.empty()))
                     .toList();
    }
}

Можно упростить: 1. Stream<String> getAllParentsStream(String key) { ... } 2. List<String> res = getAllParentsStream(key).toList();

Konstantin Makarov 11.06.2024 05:45

Другие вопросы по теме