2010-02-02 57 views
43

從ImmutableList的javadoc:google的ImmutableList和Collections.unmodifiableList()有什麼區別?

不像 Collections.unmodifiableList(java.util.List中), 這是一個單獨 集合,仍然可以改變的觀點,ImmutableList的 實例包含其 自己的私人數據並不會 更改。 ImmutableList是公共靜態最終名單 (「常數表」)方便 ,也可以讓你 容易被 呼叫者提供讓你的類 列表的「防禦性複製」。

這是否意味着:

  1. ,如果我有尺寸的ImmutableList對象(例如),那麼我不能改變它的任何尺寸的對象?
  2. 如果我有Dimension對象的Collections.unmodifiableList(列表),那麼我不僅可以添加或刪除任何對象,但我可以改變它們(例如調用setDimension(width,height)方法)?
+1

您可能還想看看[Guava的Collections.unmodifiableSet()和ImmutableSet](http://stackoverflow.com/q/5611324/977087) – Crowie 2015-04-22 15:35:06

回答

52

不,不變性僅適用於集合中對象的數量和引用,並且不涉及放入集合中的對象的可變性。

什麼不可變列表比標準JDK Collections.unmodifiableList增加的是,通過使用ImmutableList,您可以保證所引用的對象,它們的順序和列表的大小不能從任何來源改變。使用Collections.unmodifiableList,如果其他內容具有對基礎列表的引用,那麼即使您有對不可修改列表的引用,該代碼也可以修改該列表。

但是,如果您想要真正的不可變性,您必須用不可變對象填充列表。

+0

之間的區別是什麼?當然,反射... – naiad 2011-03-02 14:57:23

+0

@Vuntic,如果類是真正不可變的,它的字段被聲明爲final,並且反射不能改變它。 – Yishai 2011-03-03 14:37:20

+1

@易海,反思*可以*修改最終字段。嘗試一下。 – naiad 2011-03-06 06:56:22

14

使用Collections.unmodifiableList在您的列表中創建一個包裝。如果底層列表發生變化,那麼您的不可修改列表視圖也會變化。

正如文檔所述,Google的代碼創建了一個副本。這是一個更昂貴的計算和消耗更多的內存,但如果有人改變了原始列表,它不能影響ImmutableList。

這些都不可以防止你在列表中更改對象,或者它的領域,或字段的字段等

+2

「正如文檔所述,Google的代碼創建了一個副本。」它*可能*創建一個副本。如果原始文件也是不可變的數據結構,它實際上可以重用它。所以如果你廣泛使用'ImmutableList',你會經常碰到這種情況,最終不會複製太多。 – 2014-03-18 04:58:49

3
  1. 沒有,所包含的各個對象仍然可以修改。一個集合實際上僅將引用存儲到包含的對象中,而不是每個對象的完整副本。
  2. 您可以通過修改您調用Collections.unmodifiableList(list)的父集合來修改列表。但是,是的,您可以使用setDimension來更改存儲的列表元素。
6

ImmutableListCollections.unmodifiableList(new ArrayList(list))相似。請注意,新創建的ArrayList而不是分配給一個字段或變量。

0

你可能也想看看this question(番石榴的Collections.unmodifiableSet()ImmutableSet之間有什麼區別)。