java中深復(fù)制知識點(diǎn)詳解
在正式開始深復(fù)制的講解之前,我們先來理解一下概念。假設(shè)一個物品需要批量生產(chǎn),但是這個物品還配有贈品,生產(chǎn)的時候需要把贈品也列在計劃內(nèi)。所謂深復(fù)制的原理就是這樣,我們不能只復(fù)制屬性,包括引用之類的附帶也需要被復(fù)制。下面小編就為大家?guī)砩顝?fù)制的兩種不同方法。
1.序列化實(shí)現(xiàn)
如下為谷歌Gson序列化HashMap,實(shí)現(xiàn)深度復(fù)制的例子:
public class CopyDeepMapTest {
public static void main(String[] args) {
HashMap<Integer, User> userMap = new HashMap<>();
userMap.put(1, new User("jay", 26));
userMap.put(2, new User("fany", 25));
//Shallow clone
Gson gson = new Gson();
String jsonString = gson.toJson(userMap);
Type type = new TypeToken<HashMap<Integer, User>>(){}.getType();
HashMap<Integer, User> clonedMap = gson.fromJson(jsonString, type);
//Same as userMap
System.out.println(clonedMap);
System.out.println("\nChanges DO NOT reflect in other map \n");
//Change a value is clonedMap
clonedMap.get(1).setName("test");
//Verify content of both maps
System.out.println(userMap);
System.out.println(clonedMap);
}
}
運(yùn)行結(jié)果:
{1=User{name='jay', age=26}, 2=User{name='fany', age=25}}
Changes DO NOT reflect in other map
{1=User{name='jay', age=26}, 2=User{name='fany', age=25}}
{1=User{name='test', age=26}, 2=User{name='fany', age=25}}
從運(yùn)行結(jié)果看出,對cloneMap修改,userMap沒有被改變,所以是深度復(fù)制。
2.list深復(fù)制
兩個list數(shù)據(jù)相同但是地址值不同,A和B是獨(dú)立的兩個list,A改變了B不會改變,B改變了A也不會改變
深復(fù)制的工具類方法:
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;
}
關(guān)于深拷貝的一個擴(kuò)展實(shí)例:
public class YuelyLog implements Serializable,Cloneable {
private Attachment attachment;
private String name;
private String date;
@Override
protected YuelyLog clone() throws CloneNotSupportedException {
return (YuelyLog)super.clone();
}
public Attachment getAttachment() {
return attachment;
}
public void setAttachment(Attachment attachment) {
this.attachment = attachment;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
/**
* 使用序列化技術(shù)實(shí)現(xiàn)深拷貝
* @return
*/
public YuelyLog deepClone() throws IOException,ClassNotFoundException{
//將對象寫入流中
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
objectOutputStream.writeObject(this);
//從流中取出
ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
return (YuelyLog)objectInputStream.readObject();
}
}
相關(guān)文章
Spring Boot快速實(shí)現(xiàn) IP地址解析的示例詳解
這篇文章主要介紹了Spring Boot快速實(shí)現(xiàn)IP地址解析,本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-08-08
Spring Boot緩存實(shí)戰(zhàn) Caffeine示例
本篇文章主要介紹了Spring Boot緩存實(shí)戰(zhàn) Caffeine示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-02-02
Java Volatile關(guān)鍵字實(shí)現(xiàn)原理過程解析
這篇文章主要介紹了Java Volatile關(guān)鍵字實(shí)現(xiàn)原理過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-03-03
SpringBoot整合Druid數(shù)據(jù)庫連接池的方法
Druid是Java語言中最好的數(shù)據(jù)庫連接池。Druid能夠提供強(qiáng)大的監(jiān)控和擴(kuò)展功能。這篇文章主要介紹了SpringBoot整合Druid數(shù)據(jù)庫連接池的方法,需要的朋友可以參考下2020-07-07
淺談springfox-swagger原理解析與使用過程中遇到的坑
本篇文章主要介紹了淺談springfox-swagger原理解析與使用過程中遇到的坑,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-02-02
JAVA如何獲取jvm和操作系統(tǒng)相關(guān)信息
這篇文章主要介紹了JAVA獲取jvm和操作系統(tǒng)相關(guān)信息,使用Java自帶的類進(jìn)行獲取系統(tǒng)運(yùn)行的相關(guān)信息,在這整理記錄分享一下,需要的朋友可以參考下2022-10-10

