在Java中,要对ArrayList进行深拷贝,你可以使用clone()
方法,但这仅适用于浅拷贝,即它会创建一个新的列表实例,但列表中的元素仍然是引用类型时的共享引用。对于基本数据类型(如int、double等),这种方法可以很好地工作,但如果你有自定义对象,它们将共享相同的引用。
要进行深拷贝,你需要创建列表的新实例,并逐一复制列表中的每个元素,这通常意味着你需要实现一个复制构造函数或使用序列化/反序列化。以下是使用序列化/反序列化进行深拷贝的示例:
public static <T> List<T> deepCopy(List<T> src) throws IOException, ClassNotFoundException {
ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(byteOut);
out.writeObject(src);
ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
ObjectInputStream in = new ObjectInputStream(byteIn);
@SuppressWarnings("unchecked")
List<T> dest = (List<T>) in.readObject();
return dest;
}
public static void main(String[] args) {
List<User> userArrayList = new ArrayList<>();
for (int i = 0; i < 4; i++) {
User user = new User();
user.setUsername("user" + i);
user.setId(i);
userArrayList.add(user);
}
try {
// 进行深拷贝
List<User> userArrayList1 = deepCopy(userArrayList);
// 修改userArrayList1中的用户名,不会影响userArrayList
for (User user : userArrayList1) {
user.setUsername("user");
}
// 打印原始列表userArrayList
userArrayList.forEach(System.out::println);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
// User类需要实现Serializable接口
public class User implements Serializable {
private static final long serialVersionUID = 1L;
// 其他属性和方法
}
请注意,进行深拷贝的对象必须实现Serializable
接口,否则无法使用序列化进行复制。此外,使用序列化/反序列化进行深拷贝可能比手动复制更慢,特别是在处理大型对象或列表时。因此,当你需要复制的对象很大或列表很长时,你可能需要考虑其他方法,如使用Apache Commons Lang库中的SerializationUtils.clone()
方法,它提供了更快的深拷贝能力。