【问题标题】:How to copy a nested list without causing a StackOverflowError如何复制嵌套列表而不导致 StackOverflowError
【发布时间】:2019-10-02 01:48:52
【问题描述】:

我有一个包含许多 Team 对象的 ArrayList。我需要创建此数组列表的深层克隆,但每个 Team 对象都有一个包含更多 Team 对象的 ArrayList。当母 ArrayList 的大小达到数百个时,我得到一个 StackOverflow 错误。

我编写了一个实用函数,通过在每个元素上调用 Team::clone() 来深度克隆数组列表。 Team::clone() 被覆盖以返回 Team 对象的深层副本。 Team::clone() 包括对实用程序 deepclone 函数的调用以克隆其自己的数组列表

如果你需要代码

class Team {
    int foo;
    ArrayList<Team> teams;


    public Team(int foo, ArrayList<Team> bar){
        teams=bar;
        foo=foo;
    }

    @Override
    public Team clone(){
        new Team(foo,deepclone(teams));
    }


    public static ArrayList<Team> deepclone(ArrayList<Team> in){
        ArrayList<Team> ret=new ArrayList<>();

        for(Team t:in) {
            ret.add(t.clone());
        }

        return ret;
    }

    public static void main (String args[]){
         //already have a huge ArrayList of teams
         deepclone(thebigarraylist);
    }
}

【问题讨论】:

  • 确认一下,列表的嵌套有多深? (有多少嵌套级别的列表?)
  • 母数组内部通常只有一层,但在特殊情况下,层数可能会无限增加
  • 可以使用栈结构来模拟递归。

标签: java arrays clone


【解决方案1】:

如果有足够的嵌套级别,因此递归,StackOverflowError 是不可避免的。您可以尝试的一件事是将deepclone 内联到递归级别数的近一半,从而使允许的嵌套级别数加倍。您还可以使Team 实现Cloneable 并使deepclone 通用(重命名为deepCloneIterable)。 (注意:未经测试!)

class Team implements Cloneable {
    int foo;
    ArrayList<Team> teams;


    public Team(int foo, ArrayList<Team> bar){
        teams = bar;
        foo = foo;
    }

    @Override
    public Team clone(){
        ArrayList<Team> teamsCopy = new ArrayList<>();

        for(Team team : teams) {
            teamsCopy.add(team.clone());
        }

        return new Team(foo, teamsCopy);
    }

    public static ArrayList<T> deepCloneIterable(Iterable<T> in){
        ArrayList<T> out = new ArrayList<>();

        for(T t : in) {
            out.add(t.clone());
        }

        return out;
    }

    public static void main(String args[]){
         //already have a huge ArrayList of teams
         deepCloneIterable(thebigarraylist);
    }
}

【讨论】:

  • 我在想一些序列化的方法,但我会试试这个解决方案
  • 你可以序列化然后反序列化它,但它可能效率很低。另一种选择是通过跟踪列表或堆栈中每个深度的当前索引来手动遍历嵌套列表,如@shmosel alluded to。不过我现在得走了。
猜你喜欢
  • 1970-01-01
  • 2012-01-09
  • 1970-01-01
  • 2013-12-05
  • 1970-01-01
  • 2016-01-06
  • 1970-01-01
  • 2012-08-05
  • 2021-07-22
相关资源
最近更新 更多