ImmutableSet
のJavaDocはこう言っています:
変更可能な個別のコレクションのビューである_
Collections.unmodifiableSet
_とは異なり、このクラスのインスタンスには独自のプライベートデータが含まれ、変更されることはありません。このクラスはパブリックスタティックファイナルセット( "定数セット」)と、呼び出し元からクラスに提供されたセットの「防御コピー」を簡単に作成することもできます。
しかし、ImmutableSet
にはまだ要素の参照が格納されているため、Collections.unmodifiableSet()
との違いを理解できませんでした。サンプル:
_StringBuffer s=new StringBuffer("a");
ImmutableSet<StringBuffer> set= ImmutableSet.of(s);
s.append("b");//s is "ab", s is still changed here!
_
誰かそれを説明できますか?
このことを考慮:
Set<String> x = new HashSet<String>();
x.add("foo");
ImmutableSet<String> guava = ImmutableSet.copyOf(x);
Set<String> builtIn = Collections.unmodifiableSet(x);
x.add("bar");
System.out.println(guava.size()); // Prints 1
System.out.println(builtIn.size()); // Prints 2
言い換えると、ImmutableSet
は、コピーが作成されるため、変更された可能性があるものから構築されたコレクションに関係なく不変です。 Collections.unmodifiableSet
はreturnedコレクションが直接変更されるのを防ぎますが、それでも潜在的に変化するバッキングセットのビューです。
オブジェクトの内容の変更を開始した場合、任意のセットでreferredに変更しても、すべてのベットはとにかくオフになります。それをしないでください。実際、最初に変更可能な要素型を使用してセットを作成することは、めったにありません。 (可変キータイプを使用した同上マップ。)
Jonが言及している動作の違いに加えて、ImmutableSet
とCollections.unmodifiableSet
によって作成されたSet
の重要な違いは、ImmutableSet
がtypeであることです。コード全体でImmutableSet
ではなくSet
を使用して、セットが不変であることを明確にしておくことができます。 Collections.unmodifiableSet
を使用すると、返されるタイプはSet
...なので、Set
を渡すすべての場所にJavadocを追加しない限り、セットが作成された時点でセットを変更できないことは明らかです。
Kevin Bourrillion(Guavaのリード開発者)が、不変/変更不可能なコレクションを このプレゼンテーション で比較します。プレゼンテーションは2年前のもので、「グーバ」のサブパートである「Googleコレクション」に焦点を当てていますが、これは非常に興味深いプレゼンテーションです。 APIはあちこちで変更されている可能性がありますが(Google Collections APIは当時ベータ版でした)、Google Collections/Guavaの背後にある概念はまだ有効です。
this other SO question (googleのImmutableListとCollections.unmodifiableList()の違いは何ですか?).
他の回答で述べられていない2つの違いは、 Javadoc で説明されているように、ImmutableSet
はnull
値を許可しないことです
信頼性の高い、ユーザー指定の反復順序を備えた高性能で不変のセット。 null要素は許可されません。
(同じ制限がすべてのGuava不変コレクションの値に適用されます。)
例えば:
ImmutableSet.of(null);
ImmutableSet.builder().add("Hi").add(null); // Fails in the Builder.
ImmutableSet.copyOf(Arrays.asList("Hi", null));
これらはすべて実行時に失敗します。対照的に:
Collections.unmodifiableSet(new HashSet<>(Arrays.asList("Hi", null)));
これで結構です。