Map拷貝 關於物件深拷貝 淺拷貝的問題

2022-06-29 15:39:08 字數 1966 閱讀 4277

問題:map拷貝時發現資料會變化。

高能預警,你看到的下面的栗子是不正確的,後面有正確的一種辦法,如果需要看的話的,請看到底,感謝各同學的提醒,已做更正,一定要看到最後

先看例子:

publicclasscopymap

}上面程式的期望輸出值是,mapfrist的值均為1,

但是實際上輸出結果為:

這裡是因為map發生了淺拷貝,mapfirst只是複製了map的引用,和map仍使用同乙個記憶體區域,所以,在修改map的時候,mapfirst的值同樣會發生變化。

ps:所謂淺複製:則是只複製物件的引用,兩個引用仍然指向同乙個物件,在記憶體中占用同一塊記憶體。被複製物件的所有變數都含有與原來的物件相同的值,而所有的對其他物件的引用仍然指向原來的物件。換言之,淺複製僅僅複製所考慮的物件,而不複製它所引用的物件。

深複製:被複製物件的所有變數都含有與原來的物件相同的值,除去那些引用其他物件的變數。那些引用其他物件的變數將指向被複製過的新物件,而不再是原有的那些被引用的物件。換言之,深複製把要複製的物件所引用的物件都複製了一遍。

如何解決?

使用深拷貝,拷貝整個物件,而非引用

map中有個方法叫做putall方法,可以實現深拷貝,如下:

publicclasscopymap

}如上,輸出結果為:

參考:注意!!!注意!!!!注意!!! 上面並不是深拷貝,留下來的原因是提醒大家,這裡是存在錯誤的。(很高興你看到這裡了)

感謝下面這幾位朋友的提醒。

如何實現map的深拷貝呢?

有一種方法,是使用序列化的方式來實現物件的深拷貝,但是前提是,物件必須是實現了serializable介面才可以,map本身沒有實現 serializable 這個介面,所以這種方式不能序列化map,也就是不能深拷貝map。但是hashmap是可以的,因為它實現了 serializable。下面的方式,基於hashmap來講,非map的拷貝。

具體實現如下:

01

publicclasscloneutilscatch(exception e)

21

22

returnclonedobj;

23

}

24

}

如何使用呢,下面是個使用的例子,同時證明了map的putall方法並沒有實現深拷貝,putall僅對基本資料型別起到深拷貝的作用。

栗子:01

publicstaticvoidmain(string args)

輸出結果如下:

最上面的兩條是原始資料,使用了putall方法拷貝了乙個新的mapnew物件,

中間兩條,是修改map物件的基本資料型別的時候,並沒有影響到mapnew物件。

但是看倒數第二組,更改引用資料型別的時候,發現mapnew的值也變化了,所以putall並沒有對map產生深拷貝。

最後面是使用序列化的方式,發現,更改引用型別的資料的時候,mapnew物件並沒有發生變化,所以產生了深拷貝。

上述的工具類,可以實現物件的深拷貝,不僅限於hashmap,前提是實現了serlizeable介面。

還沒有看putall的原始碼實現,後面看下為什麼不能實現深拷貝。

Map物件的淺拷貝與深拷貝

問題 map拷貝時發現資料會變化。先看例子 public class copymap 上面程式的期望輸出值是,mapfrist的值均為1,但是實際上輸出結果為 這裡是因為map發生了淺拷貝,mapfirst只是複製了map的引用,和map仍使用同乙個記憶體區域,所以,在修改map的時候,mapfir...

js 物件深拷貝 深拷貝與淺拷貝

前言 最近在複習一些面試的知識點,剛剛好複習到了這一部分,於是就寫下這篇文章記錄一下。一 值型別和引用型別 在學習深拷貝和淺拷貝之前,我們先來了解一下js的變數型別。值型別 vs 引用型別 值型別 值型別主要有 number,string,boolean,symbol,null,undefined ...

java 複製Map物件(深拷貝與淺拷貝)

淺拷貝 只複製物件的引用,兩個引用仍然指向同乙個物件,在記憶體中占用同一塊記憶體 被複製物件的所有變數都含有與原來的物件相同的值,而所有的對其他物件的引用仍然指向原來的物件 換言之,淺複製僅僅複製所考慮的物件,而不複製它所引用的物件。深拷貝 被複製物件的所有變數都含有與原來的物件相同的值,除去那些引...