Quelle est la différence entre les Collections.unmodifiableSet() et ImmutableSet de goyave?
JavaDoc de ImmutableSet
dit:
Contrairement à
Collections.unmodifiableSet
, qui est une vue d'une collecte séparée 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 final sets publics statiques ("constant sets") et vous permet également de faire facilement une" copie défensive " d'un ensemble fourni à votre classe par un appelant.
mais le ImmutableSet
stocke encore des références d'éléments, Je ne pouvais pas comprendre la différence à Collections.unmodifiableSet()
. Exemple:
StringBuffer s=new StringBuffer("a");
ImmutableSet<StringBuffer> set= ImmutableSet.of(s);
s.append("b");//s is "ab", s is still changed here!
quelqu'un peut-il l'expliquer?
4 réponses
considérez 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 malgré toute collection qu'il est construit à partir de changer potentiellement - parce qu'il crée une copie. Collections.unmodifiableSet
empêche la collection returned d'être changée directement, mais c'est toujours une vue sur un jeu de dos pouvant changer.
Notez que si vous commencez à changer le contenu des objets visée par tout ensemble, tous les paris sont hors de toute façon. Ne pas le faire. 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 pour les cartes utilisant un type de clé mutable.)
outre la différence de comportement que Jon mentionne, une différence importante entre ImmutableSet
et le Set
créé par Collections.unmodifiableSet
est que ImmutableSet
est un type . Vous pouvez en faire circuler un et faire en sorte qu'il reste clair que l'ensemble est immuable en utilisant ImmutableSet
plutôt que Set
dans tout le code. Avec Collections.unmodifiableSet
, le type retourné est juste Set
... il est donc clair que le jeu est inmodifiable au point où il est créé à moins que vous n'ajoutiez Javadoc partout où vous passez que Set
disant"Cet ensemble est unmodifiable".
Kevin Bourrillion (développeur principal de goyaves) compare les collections immuables / non modifiables dans this presentation . Alors que la présentation a deux ans, et se concentre sur "Google Collections" (qui est maintenant une sous-partie de la goyave), il s'agit d'une très intéressante présentation . L'API peut avoir changé ici et là (L'API Google Collections était en version bêta à l'époque), mais les concepts derrière Google Collections / Goyave sont toujours valables.
vous pourriez également être intéressé par cette autre question ( Quelle est la différence entre la liste immutable de google et les Collections.unmodifiableList () ).
une différence entre les deux non mentionnée dans les autres réponses est que ImmutableSet
ne permet pas null
valeurs, comme décrit dans le Javadoc
un jeu immuable haute performance 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 dans toutes les collections immuables de goyaves.)
par exemple:
ImmutableSet.of(null);
ImmutableSet.builder().add("Hi").add(null); // Fails in the Builder.
ImmutableSet.copyOf(Arrays.asList("Hi", null));
tous ceux-ci échouent à l'exécution. En revanche:
Collections.unmodifiableSet(new HashSet<>(Arrays.asList("Hi", null)));
C'est très bien.