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

爷,独闯天下 提交于 2020-04-12 07:42:31

问题


How to resolve java.lang.StackOverflowError for the following code?

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 + "]";
    }
}

TestPerson.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);
    }
}

回答1:


All your Parent instances have the same list of children, since you construct a single ArrayList and use it as the children of all three Person. So you have a recursive data structure. Create a different list for each person.




回答2:


You can have an overloaded constructor in Person class without the need to pass a List for children attribute.

class Person

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 + "]";
    }
}

And then in class TestPerson do this:

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);
    }
}



回答3:


You are using the same list for children of different persons. Remove children argument from your constructor and do children = new ArrayList<>() in the constructor.




回答4:


p1, p2, and p3 -- all are adding the same emptylist as their children, so when you're adding p3 as children of p2, and then it as the children of p1, it's basically like saying: add emptylist to emptylist continuously, causing a stack overflow because of the indefinite recursion!

What you need to do instead? Create a new list for every Person's children, like:

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);


来源:https://stackoverflow.com/questions/59345674/java-lang-stackoverflowerror-when-trying-to-add-the-same-instance-of-list-multip

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!