Как скопировать вложенный список, не вызывая StackOverflowError - PullRequest
0 голосов
/ 15 мая 2019

У меня есть ArrayList, содержащий много объектов Team. Мне нужно создать глубокий клон этого массива, но у каждого объекта Team есть ArrayList из большего количества объектов Team. Когда размер материнского 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);
    }
}

1 Ответ

0 голосов
/ 15 мая 2019

Если уровней вложенности достаточно и, следовательно, рекурсия, 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);
    }
}
...