Quelle est la différence entre Collections.unmodifiableSet () et ImmutableSet of Guava?

JavaDoc de ImmutableSet dit:

Contrairement à Collections.unmodifiableSet , qui est une vue d’une collection distincte pouvant 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 ne pouvais pas comprendre la différence avec Collections.unmodifiableSet() . Échantillon:

 SsortingngBuffer s=new SsortingngBuffer("a"); ImmutableSet 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 x = new HashSet(); x.add("foo"); ImmutableSet guava = ImmutableSet.copyOf(x); Set 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 sur laquelle il est potentiellement construit, car il crée une copie. Collections.unmodifiableSet empêche que la collection renvoyée ne soit directement modifiée, mais cela rest une vue d’un ensemble de sauvegarde potentiellement modifié.

    Notez que si vous commencez à modifier le contenu des objects référencés par un ensemble, tous les paris sont désactivés. Ne fais pas ça. En effet, il est rarement judicieux de créer un ensemble en utilisant un type d’élément mutable en premier lieu. (Idem cartes utilisant un type de clé mutable.)

    Outre la différence de comportement mentionnée par Jon, une différence importante entre ImmutableSet et l’ Set créé par Collections.unmodifiableSet est ImmutableSet est un type . Vous pouvez en passer un et garder à l’esprit que l’ensemble est immuable en utilisant ImmutableSet plutôt que Set dans le code. Avec Collections.unmodifiableSet , le type renvoyé est simplement Set … il est donc clair que l’ensemble n’est pas modifiable à l’endroit où il est créé, sauf si vous ajoutez Javadoc partout où vous passez cet Set disant “cet ensemble est modifiable”.

    Kevin Bourrillion (développeur principal de Guava) compare les collections immuables / non modifiables de cette présentation . Bien que la présentation ait deux ans et se concentre sur “Google Collections” (qui est maintenant une sous-partie de Guava), il s’agit d’une présentation très intéressante . L’API a peut-être changé ici et là (l’API des collections Google était en version bêta à l’époque), mais les concepts derrière Google Collections / Guava sont toujours valables.

    Vous pourriez également être intéressé par cette autre question SO ( Quelle est la différence entre ImmutableList de Google et Collections.unmodifiableList () ).

    Une différence entre les deux non mentionnés dans d’autres réponses est que ImmutableSet ne permet pas null valeurs null , comme décrit dans le Javadoc

    Un ensemble immuable hautes performances avec un ordre d’itération fiable et défini par l’utilisateur. Ne permet pas d’éléments nuls.

    (La même ressortingction s’applique aux valeurs de toutes les collections immuables de Guava.)

    Par exemple:

     ImmutableSet.of(null); ImmutableSet.builder().add("Hi").add(null); // Fails in the Builder. ImmutableSet.copyOf(Arrays.asList("Hi", null)); 

    Tout cela échoue à l’exécution. En revanche:

     Collections.unmodifiableSet(new HashSet<>(Arrays.asList("Hi", null))); 

    C’est bon.