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?

36
demandé sur ROMANIA_engineer 2011-04-10 15:07:22

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.)

72
répondu Jon Skeet 2011-04-10 11:23:07

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".

15
répondu ColinD 2011-04-10 16:27:42

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 () ).

10
répondu Etienne Neveu 2017-05-23 12:34:18

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.

2
répondu Andy Turner 2016-04-22 07:40:52