如何高效地深度克隆以数组列表为字段的对象数组

问题描述 投票:0回答:3

最深元素:

class Player {
    //fields contain:
    int value;
}

收集于:

class Team {
    //fields contain:
    ArrayList<Player> players;
}

收集于:

class Splitter {
    //fields contain:
    Teams[] teams;
}

Splitter
中的函数中,我必须克隆
teams
。我基本上必须通过克隆每个
teams
对象来克隆数组
Team
,每个对象都包含一个我必须克隆的 ArrayList
players
。我不想想要克隆 Player 对象本身。

到目前为止我的解决方案看起来像这样:

private Team[] deepClone(Team[] teams) {
    Team[] new_teams = new Team[teams.length];
    for (int i = 0; i < teams.length; i++) {
        new_teams[i] = new Team();
        for (Player player : teams[i].getPlayers())
            new_teams[i].getPlayers().add(player);
    }
    return new_teams;
}

我可以做哪些改变来使其更高效或更优雅?

java arrays arraylist clone deep-copy
3个回答
0
投票

您当前的解决方案相当于这个更简单的形式:

private Team[] deepClone(Team[] teams) {
    Team[] new_teams = new Team[teams.length];
    for (int i = 0; i < teams.length; i++) {
        new_teams[i] = new Team();
        new_teams[i].getPlayers().addAll(teams[i].getPlayers());
    }
    return new_teams;
}

您可以使用流和 lambda 使其更加优雅,而无需循环索引:

private Team[] deepClone(Team[] teams) {
    return Stream.of(teams).map(team -> {
        Team newTeam = new Team();
        return newTeam.getPlayers().addAll(team.getPlayers());
    }).toArray(Team[]::new);
}

0
投票

理想情况下,如果您想进行完美的深度克隆,您也应该克隆玩家,我们应该始终在每个类中编写克隆方法,然后调用该克隆方法来获取克隆,无论如何您可以采用以下方式。

class Team {
        //fields contain:
        ArrayList<Player> players;
        public Team clone() {
           Team team = new Team();
           team.players.addAll(players);
           return team;
        }
    }

// ...

    Team[] deepCloneTeams(Team[] teams) {
        Team[] newTeams = new Team[teams.length];
        for (int i = 0; i < teams.length; i++)
            newTeams[i] = teams[i].clone();
        return newTeams;
    }

0
投票

从技术上讲,你不是克隆玩家,你使用的是相同的玩家参考。 如果您想实际克隆玩家,您应该有一些方法来实例化新玩家并复制玩家的(原始)值并克隆玩家的对象属性。

大致如下:

class Player{
    // your attributes and methods
    Player getClone(){
        Player p = new Player();
        // set all attributes and clone all attribute objects
        return p;
    }
}

class Team {
    //fields contain:
    ArrayList<Player> players;
    public Team clone() {
        Team team = new Team();
        team.players.addAll(players.stream().forEach(p->p.getClone()).collect(Collectors.toList());
        return team;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.