java.lang.StackOverflowError 尝试多次添加相同的列表实例时

java.lang.StackOverflowError when trying to add the same instance of list multiple times

如何解决 java.lang.WhosebugError 以下代码?

Person.java

import java.util.List;

public class Person {
    private String name;
    private List<Person> children;
    public Person() {
    }
    public Person(String name, List<Person> children) {
        this.name = name;
        this.children = children;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public List<Person> getChildren() {
        return children;
    }
    public void setChildren(List<Person> children) {
        this.children = children;
    }
    @Override
    public String toString() {
        return "Person [name=" + name + ", children=" + children + "]";
    }
}

测试Person.java

import java.util.ArrayList;
import java.util.List;

public class TestPerson {
    public static void main(String[] args) {
        List<Person> emptylist = new ArrayList<Person>();
        Person p3 = new Person("X", emptylist);
        Person p2 = new Person("Y", emptylist);
        Person p1 = new Person("Z", emptylist);
        p2.getChildren().add(p3);
        p1.getChildren().add(p2);
        System.out.println(p1);
    }
}

您正在为 children 不同的人使用相同的列表。 从构造函数中删除 children 参数并在构造函数中执行 children = new ArrayList<>()。

您的所有 Parent 实例都具有相同的子项列表,因为您构建了一个 ArrayList 并将其用作所有三个 Person 的子项。所以你有一个递归数据结构。为每个人创建不同的列表。

p1p2p3 -- 都在添加与它们的 children 相同的 emptylist,因此当您添加 p3 作为 p2 的 children,然后作为 p1 的 children,基本上就像说:将 emptylist 添加到 emptylist ] 不断,因为无限递归导致栈溢出!

您需要做什么?为每个人的 children 创建一个新列表,例如:

List<Person> emptylist1 = new ArrayList<Person>();
List<Person> emptylist2 = new ArrayList<Person>();
List<Person> emptylist3 = new ArrayList<Person>();

Person p3 = new Person("X", emptylist1);
Person p2 = new Person("Y", emptylist2);
Person p1 = new Person("Z", emptylist3);

p2.getChildren().add(p3);
p1.getChildren().add(p2);

您可以在 Person class 中使用重载构造函数,而无需为子属性传递 List

class人

import java.util.List;

public class Person {
    private String name;
    private List<Person> children;

    public Person() {
    }

    public Person(String name) {
        this(name,new ArrayList<Person>());
    }

    public Person(String name, List<Person> children) {
        this.name = name;
        this.children = children;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public List<Person> getChildren() {
        return children;
    }
    public void setChildren(List<Person> children) {
        this.children = children;
    }
    @Override
    public String toString() {
        return "Person [name=" + name + ", children=" + children + "]";
    }
}

然后在 class TestPerson 中执行此操作:

import java.util.ArrayList;
import java.util.List;

public class TestPerson {
    public static void main(String[] args) {
        Person p3 = new Person("X");
        Person p2 = new Person("Y");
        Person p1 = new Person("Z");
        p2.getChildren().add(p3);
        p1.getChildren().add(p2);
        System.out.println(p1);
    }
}