JavaDoc de ImmutableSet
dit:
Contrairement à
Collections.unmodifiableSet
, Qui est une vue d'une collection distincte qui peut encore changer, une instance de cette classe contient ses propres données privées et ne changera jamais. Cette classe est pratique pour les ensembles finaux statiques publics ( "ensembles constants") et vous permet également de faire facilement une "copie défensive" d'un ensemble fourni à votre classe par un appelant.
Mais le ImmutableSet
stocke toujours la référence des éléments, je n'ai pas pu comprendre la différence avec Collections.unmodifiableSet()
. Échantillon:
StringBuffer s=new StringBuffer("a");
ImmutableSet<StringBuffer> set= ImmutableSet.of(s);
s.append("b");//s is "ab", s is still changed here!
Quelqu'un pourrait-il l'expliquer?
Considère ceci:
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
En d'autres termes, ImmutableSet
est immuable, quelle que soit la collection à partir de laquelle il est potentiellement modifié, car il crée une copie. Collections.unmodifiableSet
empêche la modification directe de la collection retournée, mais c'est toujours une vue sur un ensemble de supports potentiellement changeant.
Notez que si vous commencez à changer le contenu des objets référencé par n'importe quel ensemble, tous les paris sont de toute façon désactivés. Ne fais pas ça. En effet, c'est rarement une bonne idée de créer un ensemble en utilisant un type d'élément mutable en premier lieu. (Idem mappe en utilisant un type de clé mutable.)
Outre la différence de comportement mentionnée par Jon, une différence importante entre ImmutableSet
et Set
créée par Collections.unmodifiableSet
est que ImmutableSet
est un type. Vous pouvez en passer un et garder clair que l'ensemble est immuable en utilisant ImmutableSet
plutôt que Set
dans tout le code. Avec Collections.unmodifiableSet
, le type renvoyé est simplement Set
... il est donc clair que l'ensemble n'est pas modifiable au point où il est créé, sauf si vous ajoutez Javadoc partout où vous passez ce Set
en disant "this l'ensemble n'est pas modifiable ".
Kevin Bourrillion (développeur principal de Guava) compare les collections immuables/non modifiables dans cette présentation . Bien que la présentation ait deux ans et se concentre sur "Google Collections" (qui est maintenant une sous-partie de la goyave), il s'agit d'une présentation très intéressante . L'API a peut-être changé ici et là (l'API Google Collections était en version bêta à l'époque), mais les concepts derrière Google Collections/Guava sont toujours valides.
Vous pourriez également être intéressé par cette autre SO question ( Quelle est la différence entre Google ImmutableList et Collections.unmodifiableList ()) .
Une différence entre les deux non mentionnées dans les autres réponses est que ImmutableSet
ne permet pas les valeurs null
, comme décrit dans Javadoc
Un ensemble hautes performances immuable avec un ordre d'itération fiable et spécifié par l'utilisateur. Ne permet pas les éléments nuls.
(La même restriction s'applique aux valeurs de toutes les collections immuables de Goyave.)
Par exemple:
ImmutableSet.of(null);
ImmutableSet.builder().add("Hi").add(null); // Fails in the Builder.
ImmutableSet.copyOf(Arrays.asList("Hi", null));
Tous ces éléments échouent au moment de l'exécution. En revanche:
Collections.unmodifiableSet(new HashSet<>(Arrays.asList("Hi", null)));
C'est bon.