本文将从多个方面介绍Java复制List的方法,包括浅拷贝、深拷贝、使用循环、使用Java8新特性等方法。
一、浅拷贝
浅拷贝是指复制了一个对象,但是这个对象的引用类型的属性还是指向原对象的属性。Java中的ArrayList自带了clone()方法,可以实现浅拷贝。
ArrayList list1 = new ArrayList<>();
list1.add("a");
list1.add("b");
list1.add("c");
// 浅拷贝
ArrayList list2 = (ArrayList) list1.clone();
以上代码中,通过调用ArrayList的clone()方法,实现了浅拷贝。可以修改list2的元素,但是修改list2中的引用类型属性仍旧会影响到list1。
二、深拷贝
深拷贝是指复制了一个对象以及它所有的引用类型属性所指向的对象。由于Java中没有提供深拷贝的默认实现,我们可以使用一些自定义的方法进行深拷贝。
方法一:实现Cloneable接口的深拷贝
class Student implements Cloneable {
private String name;
private int age;
private List subjects;
// getter & setter...
@Override
protected Object clone() throws CloneNotSupportedException {
Student student = (Student) super.clone();
student.subjects = new ArrayList<>(this.subjects);
return student;
}
}
// 深拷贝
Student student1 = new Student();
student1.setName("小明");
student1.setAge(18);
List subjects1 = new ArrayList<>();
subjects1.add("数学");
subjects1.add("语文");
student1.setSubjects(subjects1);
Student student2 = (Student) student1.clone();
以上代码中,通过实现Cloneable接口并覆写clone()方法,在clone()方法中对引用类型进行深拷贝,从而实现了深拷贝。
方法二:使用序列化/反序列化进行深拷贝
class Student implements Serializable {
private String name;
private int age;
private List subjects;
// getter & setter
}
// 深拷贝
Student student1 = new Student();
student1.setName("小明");
student1.setAge(18);
List subjects1 = new ArrayList<>();
subjects1.add("数学");
subjects1.add("语文");
student1.setSubjects(subjects1);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(student1);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
Student student2 = (Student) ois.readObject();
以上代码中,通过将对象序列化为字节数组,再将字节数组反序列化为对象的方式,实现了深拷贝。
三、使用循环复制
循环复制是指使用for循环遍历原List,将元素逐个添加到新List中。这种方式比较复杂,但是可以根据实际需求进行灵活的操作。
List list1 = new ArrayList<>();
list1.add("a");
list1.add("b");
list1.add("c");
// 使用循环复制
List list2 = new ArrayList<>();
for (String str : list1) {
list2.add(str);
}
四、使用Java8新特性
Java8新特性中增加了一些对List的操作方法,可以更便捷的对List进行操作,包括复制。
方法一:使用stream()、map()、collect(Collectors.toList())进行复制
List list1 = new ArrayList<>();
list1.add("a");
list1.add("b");
list1.add("c");
// 复制list1到list2
List list2 = list1.stream().map(String::new).collect(Collectors.toList());
以上代码中,使用map()方法将list1中的元素转换成一个新的String对象,最后使用collect()方法将新的Stream转换成List对象。
方法二:使用Collections.copy()方法进行复制
List list1 = new ArrayList<>();
list1.add("a");
list1.add("b");
list1.add("c");
// 复制list1到list2
List list2 = new ArrayList<>();
Collections.copy(list2, list1);
以上代码中,使用Collections.copy()方法可以将数据从原List复制到目标List中。
总结
本文介绍了Java中复制List的多种方法,包括浅拷贝、深拷贝、使用循环、使用Java8新特性等方法。每种方法都有其适用的场景,需要根据具体情况进行选择。