【问题标题】:Creating a nested object structure from a list of data [closed]从数据列表创建嵌套对象结构[关闭]
【发布时间】:2018-11-24 11:59:16
【问题描述】:

我有一个如下所示的数据列表:

A [example 1]
B [example 2]
C [example 3]
C [example 4]
B [example 5]
C [example 6]

文本的每一行代表一个对象,属于它上面的对象类型。我想创建一个嵌套对象结构来表示它,因此主类 A 将包含 B 的列表(示例 2 和 5),而类 B 将包含 C 的列表(示例 2将包含 3 和 4,示例 5 将包含 6)。 A、B 和 C 是深度指标,A 是根节点,任意数量的后续节点是它的子节点。为了澄清,每个节点将始终属于其正上方的父节点,但可能有 0 多个节点。即有可能:

A [example 1]
B [example 2]

但不是

A [example 1]
C [example 2]

因为 C 必须属于它的父 B。

我正在寻找的是有人指出我正确的方向以找到一个巧妙的解决方案(可能通过递归?),这是大量的数据,所以理想情况下我只想遍历列表一次,而我所做的任何看似接近解决方案的事情都令人难以置信地混淆了。

【问题讨论】:

  • ABC等深度指标吗?你想要什么并不完全清楚。 摄取中没有递归,您只需要迭代并跟踪您正在向哪个节点添加数据,例如推送和弹出。
  • 确切地说,A 将是根节点,B 深度 1,C 深度 2 等等。你是对的,我不认为递归是我在这里所追求的,我正在寻找以一种简洁的方式来跟踪我要添加到的节点

标签: java list loops recursion


【解决方案1】:

你的问题看起来很酷!我自己试过了,我确实想出了一些东西。请不要因为代码而评判我;它有点乱,但我也试图解决它。

我理解您希望将一系列对象转换为树数据结构的问题...

代码假定您总是有一个结构为 A>B>C 的列表。例如:A>C 不起作用。此外,我假设您总是从根节点 A 开始。

public class SO_Nested {

    public static class A {
        public List<B> classesOfB = new ArrayList<>();

        public void addTree(List<Object> objects) {

            for (int i = 0; i < objects.size(); i++) {

                List<Object> addUnder = new ArrayList<>();

                B currentB = (B)objects.get(i);

                classesOfB.add(currentB);

                while(i < objects.size() - 1 && C.class.isInstance(objects.get(i + 1))) {
                    addUnder.add(objects.get(i + 1));
                    i++;
                }

                currentB.addTree(addUnder);
            }
        }
    }

    public static class B {
        public List<C> classesOfC = new ArrayList<>();

        public void addTree(List<Object> objects) {
            classesOfC.addAll(objects.stream().map(C.class::cast).collect(Collectors.toList()));
        }
    }

    public static class C {

    }

    public static void main(String[] args) {
        List<Object> allClasses = generateClassesOfA();
        allClasses.addAll(generateClassesOfB());
        allClasses.addAll(generateClassesOfC());
        allClasses.addAll(generateClassesOfB());
        allClasses.addAll(generateClassesOfC());
        allClasses.addAll(generateClassesOfA());
        allClasses.addAll(generateClassesOfB());
        allClasses.addAll(generateClassesOfB());
        allClasses.addAll(generateClassesOfC());

        List<A> sturcture = new ArrayList<>();

        for (int i = 0; i < allClasses.size(); i++) {

            List<Object> addUnder = new ArrayList<>();

            A currentA = (A)allClasses.get(i);
            sturcture.add(currentA);

            while(i < allClasses.size() - 1 && !A.class.isInstance(allClasses.get(i + 1))) {
                addUnder.add(allClasses.get(i + 1));
                i++;
            }

            currentA.addTree(addUnder);
        }

        System.out.println("");
    }




    private static List<Object> generateClassesOfA() {
        return IntStream.range(0, 1).mapToObj((unused) -> new A()).collect(Collectors.toList());
    }

    private static List<Object> generateClassesOfB() {
        return IntStream.range(0, 2).mapToObj((unused) -> new B()).collect(Collectors.toList());
    }

    private static List<Object> generateClassesOfC() {
        return IntStream.range(0, 2).mapToObj((unused) -> new C()).collect(Collectors.toList());
    }
}

【讨论】:

    【解决方案2】:

    这似乎是一个树问题。你可以有一个 Node 类,它会有另一个 Node 的列表。

    class Node {
        public Node parent;
        public List<Node> children;
    }
    

    当您看到后续字母时,您可以移动到当前节点的子节点并将值添加到子节点列表中。如果你看到前面的字母,你必须回到父节点。

    希望对你有帮助

    【讨论】:

      猜你喜欢
      • 2017-08-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-23
      • 1970-01-01
      • 1970-01-01
      • 2016-02-12
      • 1970-01-01
      相关资源
      最近更新 更多