不修改Player与Hero类时,如何实现Player列表深拷贝且不影响原Vector
不修改Player与Hero类时,如何实现Player列表深拷贝且不影响原Vector
兄弟,我一眼就瞅出问题在哪了!你在createPlayerCopy方法里用反射复制所有非ID/Name的字段时,把原Player的heroes Vector直接赋值给了拷贝出来的Player对象——这就导致原Player和拷贝Player共享同一个Vector引用!所以你调用copyPlayer.addHero(copyHero)的时候,其实是往原对象的Vector里也加了一份,自然就出现重复英雄的情况了。
我们只需要在createPlayerCopy方法里,手动给拷贝出来的Player初始化一个全新的空Vector,覆盖掉反射复制过来的原Vector引用就行,具体修改如下:
private Player createPlayerCopy(Player player) throws Exception { Class<?> clazz = player.getClass(); // 创建Player实例 Player copyPlayer = (Player) clazz.getDeclaredConstructor(String.class, String.class).newInstance(player.getPlayerID(), player.getPlayerName()); // 重点:手动初始化独立的空Vector,替换反射复制的原Vector引用 Field heroesField = clazz.getDeclaredField("heroes"); heroesField.setAccessible(true); heroesField.set(copyPlayer, new Vector<>(2, 1)); // 和原Player构造器的初始化参数保持一致 // 复制其他自定义字段(排除ID、Name和已经处理的heroes) for (java.lang.reflect.Field field : clazz.getDeclaredFields()) { if (!field.getName().equals("playerID") && !field.getName().equals("playerName") && !field.getName().equals("heroes")) { field.setAccessible(true); field.set(copyPlayer, field.get(player)); } } return copyPlayer; }
这样修改后,拷贝出来的Player拥有完全独立的heroes Vector,你往里面添加拷贝的Hero时,原Player的Vector根本不会受到影响,完美解决重复英雄的问题。
另外提一句,你原来getDeepCopy方法里的playerHero.addAll(player.getHeroes())其实可以直接简化为遍历player.getHeroes()返回的拷贝Vector,不过这不是核心问题,不影响最终结果。
备注:内容来源于stack exchange,提问作者Blueyu
相关产品推荐
相关产品推荐

