最深元素:
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;
}
我可以做哪些改变来使其更高效或更优雅?
您当前的解决方案相当于这个更简单的形式:
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);
}
理想情况下,如果您想进行完美的深度克隆,您也应该克隆玩家,我们应该始终在每个类中编写克隆方法,然后调用该克隆方法来获取克隆,无论如何您可以采用以下方式。
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;
}
从技术上讲,你不是克隆玩家,你使用的是相同的玩家参考。 如果您想实际克隆玩家,您应该有一些方法来实例化新玩家并复制玩家的(原始)值并克隆玩家的对象属性。
大致如下:
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;
}
}