Map做到深拷貝

2021-08-03 08:19:46 字數 1834 閱讀 1052

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

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

先看例子:

public class copymap

}

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

但是實際上輸出結果為:

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

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

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

如何解決?

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

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

public class copymap

}

如上,輸出結果為:

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

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

如何實現map的深拷貝呢?

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

具體實現如下:

01publicclasscloneutilscatch(exception e)

21

22returnclonedobj;

23}

24}

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

栗子:01publicstaticvoidmain(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...

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

問題 map拷貝時發現資料會變化。高能預警,你看到的下面的栗子是不正確的,後面有正確的一種辦法,如果需要看的話的,請看到底,感謝各同學的提醒,已做更正,一定要看到最後 先看例子 publicclasscopymap 上面程式的期望輸出值是,mapfrist的值均為1,但是實際上輸出結果為 這裡是因為...

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

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