コンテキスト
データキャッシュに使用しているマップへの参照を返す必要があり、参照を誰も変更できないようにします。
質問
UnmodifiableMapとImmutableMapへの多くの参照をオンラインで見ましたが、それらを比較/比較するものは見ません。 Google/Guavaが独自のバージョンを作成したのには十分な理由があると思います-誰かがそれを教えてもらえますか?
変更不可能なマップは変更される可能性があります。これは、変更可能なマップ上のviewのみであり、バッキングマップの変更は変更不可能なマップを通して表示されます。変更不可能なマップは、変更不可能なビューへの参照のみを持つユーザーの変更のみを防止します。
Map<String, String> realMap = new HashMap<String, String>();
realMap.put("A", "B");
Map<String, String> unmodifiableMap = Collections.unmodifiableMap(realMap);
// This is not possible: It would throw an
// UnsupportedOperationException
//unmodifiableMap.put("C", "D");
// This is still possible:
realMap.put("E", "F");
// The change in the "realMap" is now also visible
// in the "unmodifiableMap". So the unmodifiableMap
// has changed after it has been created.
unmodifiableMap.get("E"); // Will return "F".
それとは対照的に、グアバのImmutableMapは本当にimmutableです:これは与えられたマップの真のcopyであり、誰もこのImmutableMapを何らかの方法で変更します。
更新:
comment で指摘したように、不変マップは標準APIを使用して作成することもできます
Map<String, String> immutableMap =
Collections.unmodifiableMap(new LinkedHashMap<String, String>(realMap));
これにより、指定されたマップの真のコピーに変更不可能なビューが作成されるため、Guavaに依存関係を追加することなくImmutableMap
の特性をうまくエミュレートできます。
ImmutableMap JavaDocをご覧ください: doc
それについての情報があります:
Collections.unmodifiableMap(Java.util.Map)(変更可能な別のマップのビュー)とは異なり、ImmutableMapのインスタンスには独自のデータが含まれ、変更されることはありません。 ImmutableMapは、パブリックな静的最終マップ(「定数マップ」)に便利であり、呼び出し元がクラスに提供するマップの「防御コピー」を簡単に作成できます。
JDKは
Collections.unmodifiableXXX
メソッドを提供しますが、私たちの意見では、これらは扱いにくく冗長になる可能性があります。防御的なコピーを安全でない場所で使用するのは不快です:元のコレクションへの参照を保持している人がいない場合にのみ、返されるコレクションは本当に不変です:データ構造には、変更可能なコレクションの同時オーバーヘッド、ハッシュテーブルなど.
ImmutableMapはnull
値を受け入れませんが、Collections.unmodifiableMap()
は受け入れます。さらに、UnmodifiableMap
は変更される場合がありますが、作成後に変更されることはありません。 JavaDocから:
信頼できるユーザー指定の反復順序を持つ、不変のハッシュベースのマップ。 nullキーまたは値を許可しません。
Collections.unmodifiableMap(Java.util.Map)(変更可能な別のマップのビュー)とは異なり、ImmutableMapのインスタンスには独自のデータが含まれ、変更されることはありません。 ImmutableMapは、パブリックな静的最終マップ(「定数マップ」)に便利であり、呼び出し元がクラスに提供するマップの「防御コピー」を簡単に作成できます。