众所周知,list本质上是数组,而数组的是以地址的形式进行存储。
如上图将list A浅拷贝给list B,由于进行的是浅拷贝,所以直接将A的内容复制给了B,java中相同内容的数组指向同一地址,即进行浅拷贝后A与B指向同一地址。
造成的后果就是,改变B的同时也会改变A,因为改变B就是改变B所指向地址的内容,由于A也指向同一地址,所以A与B一起改变。
1、遍历循环复制
List
for(Person p : srcList){
destList.add(p);
}
2、使用List实现类的构造方法
List
3、使用list.addAll()方法
List
destList.addAll(srcList);
4、使用System.arraycopy()方法
Person[] srcPersons=srcList.toArray(new Person[0]);
Person[] destPersons=new Person[srcPersons.length];
System.arraycopy(srcPersons, 0, destPersons, 0, srcPersons.length);
printList(destList); //打印未改变B之前的A
srcList.get(0).setAge(100);//改变B
printList(destList); //打印改变B后的A
//打印结果
123-->20
ABC-->21
abc-->22
123-->100
ABC-->21
abc-->22
如图,深拷贝就是将A复制给B的同时,给B创建新的地址,再将地址A的内容传递到地址B。ListA与ListB内容一致,但是由于所指向的地址不同,所以改变相互不受影响。
public class TechSysVo {
@Getter
@Setter
private Long id;
@Getter
@Setter
private String name;
public TechSysVo() {
}
}
import com.wsh.clone.arraylist.TechSysVo;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class App {
public static void main(String\[\] args) {
TechSysVo techSysVo = new TechSysVo();
TechSysVo techSysVo1 = new TechSysVo();
List<TechSysVo> list = new ArrayList<>();
list.add(techSysVo);
list.add(techSysVo1);
//list深度拷贝
List<TechSysVo> newList = new ArrayList<>();
CollectionUtils.mergeArrayIntoCollection(new Object\[list.size()\],newList);
Collections.copy(newList, list);
//拷贝完清空result
list.clear();
System.out.println(list.toString());
System.out.println(newList.toString());
}
}
public class TechSysVo implements Serializable {
@Getter
@Setter
private Long id;
@Getter
@Setter
private String name;
public TechSysVo() {
}
}
public static
try {
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;
}catch (Exception e){
e.printStackTrace();
}
return null;
}
public static void main(String[] args) {
TechSysVo techSysVo = new TechSysVo();
TechSysVo techSysVo1 = new TechSysVo();
List
list.add(techSysVo);
list.add(techSysVo1);
//list深度拷贝
List
newList = deepCopy(list);
//拷贝完清空result
list.clear();
System.out.println(list.toString());
System.out.println(newList.toString());
}
public static void main(String[] args) {
TechSysVo techSysVo = new TechSysVo();
TechSysVo techSysVo1 = new TechSysVo();
List
list.add(techSysVo);
list.add(techSysVo1);
//list深度拷贝
List
//拷贝完清空result
list.clear();
System.out.println(list.toString());
System.out.println(newList.toString());
}
在浅复制的情况下,源数据被修改破坏之后,使用相同引用指向该数据的目标集合中的对应元素也就发生了相同的变化。
因此,在需求要求必须深复制的情况下,要是使用上面提到的方法,请确保List中的T类对象是不易被外部修改和破坏的。
手机扫一扫
移动阅读更方便
你可能感兴趣的文章