【问题标题】:java.lang.StackOverflowError when trying to add the same instance of list multiple times尝试多次添加相同的列表实例时出现 java.lang.StackOverflowError
【发布时间】:2020-04-08 06:29:05
【问题描述】:

以下代码如何解析java.lang.StackOverflowError

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

【问题讨论】:

    标签: java arraylist tostring


    【解决方案1】:

    您可以在 Person 类中拥有一个重载的构造函数,而无需为 children 属性传递 List

    类人

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案3】:

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

        【讨论】:

          【解决方案4】:

          p1p2p3 - 都添加了相同的 emptylist 作为它们的孩子,所以当你添加 p3 作为 p2 的孩子时,然后它作为p1的children,基本上就是在说:不断地把emptylist加到emptylist上,因为无限递归导致栈溢出!

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

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2020-02-03
            • 1970-01-01
            • 2016-04-17
            • 1970-01-01
            • 2013-01-21
            • 1970-01-01
            • 2013-10-18
            • 2023-03-06
            相关资源
            最近更新 更多