Collections immuables Java

À partir de la documentation de Java 1.6 Collection Framework :

Les collections qui ne prennent en charge aucune opération de modification (telle que l’ add , la remove et la remove ) sont appelées non modifiables . […] Les collections qui garantissent en outre qu’aucun changement dans l’object Collection ne sera jamais visible sont considérées comme immuables .

Le second critère me confond un peu. Étant donné que la première collection n’est pas modifiable, et en supposant que la référence de collection originale a été supprimée, quels sont les changements mentionnés à la deuxième ligne? S’agit-il de l’évolution des éléments de la collection, c’est-à-dire de l’état des éléments?

Deuxième question:
Pour qu’une collection soit immuable, comment peut-on fournir les garanties supplémentaires spécifiées? Si l’état d’un élément de la collection est mis à jour par un thread, est-il suffisant que ces mises à jour dans l’état ne soient pas visibles sur le thread contenant la collection immuable?

Pour qu’une collection soit immuable, comment peut-on fournir les garanties supplémentaires spécifiées?

    Les collections non modifiables sont généralement des vues en lecture seule (wrappers) d’autres collections. Vous ne pouvez pas les append, les supprimer ou les supprimer, mais la collection sous-jacente peut changer.

    Les collections immuables ne peuvent pas être changées – elles ne recouvrent pas une autre collection – elles ont leurs propres éléments.

    Voici une citation de ImmutableList de goyave

    Contrairement à Collections.unmodifiableList(java.util.List) , qui est une vue d’une collection distincte pouvant encore changer, une instance de ImmutableList contient ses propres données privées et ne changera jamais.

    Donc, fondamentalement, pour obtenir une collection immuable à partir d’une collection mutable, vous devez copier ses éléments dans la nouvelle collection et interdire toutes les opérations.

    La différence est que vous ne pouvez pas avoir de référence à une collection immuable qui permet des changements. Les collections non modifiables ne peuvent pas être modifiées via cette référence , mais un autre object peut pointer vers les mêmes données via lesquelles il peut être modifié.

    par exemple

     List ssortingngs = new ArrayList(); List unmodifiable = Collections.unmodifiableList(ssortingngs); unmodifiable.add("New ssortingng"); // will fail at runtime ssortingngs.add("Aha!"); // will succeed System.out.println(unmodifiable); 
     Collection c1 = new ArrayList(); c1.add("foo"); Collection c2 = Collections.unmodifiableList(c1); 

    c1 est mutable (c’est-à-dire ni modifiable ni immuable ).
    c2 n’est pas modifiable : il ne peut pas être changé lui-même, mais si plus tard je change c1 alors ce changement sera visible dans c2 .

    C’est parce que c2 est simplement un wrapper autour de c1 et pas vraiment une copie indépendante. Guava fournit l’ interface ImmutableList et certaines implémentations. Celles-ci fonctionnent en créant une copie de l’entrée (à moins que l’entrée ne soit une collection immuable).

    Concernant votre deuxième question:

    La mutabilité / immuabilité d’une collection ne dépend pas de la mutabilité / immutabilité des objects qui y sont contenus. La modification d’un object contenu dans une collection ne compte pas comme une “modification de la collection” pour cette description. Bien sûr, si vous avez besoin d’une collection immuable, vous souhaitez généralement qu’elle contienne des objects immuables.

    Maintenant, java 9 a des méthodes d’usine pour les listes, les ensembles, les cartes et les cartes.

    Dans Java SE 8 et versions antérieures, nous pouvons utiliser des méthodes utilitaires de classe Collections telles que unmodifiableXXX pour créer des objects Collection immuables.

    Toutefois, ces méthodes Collections.unmodifiableXXX sont une approche très fastidieuse et verbeuse. Pour pallier ces inconvénients, Oracle corp a ajouté quelques méthodes utilitaires aux interfaces List, Set et Map.

    Maintenant, dans java 9: ​​- Les interfaces List et Set ont des méthodes «of ()» pour créer une liste ou des objects immuables vide ou vide, comme indiqué ci-dessous:

    Exemple de liste vide

     List immutableList = List.of(); 

    Exemple de liste non vide

     List immutableList = List.of("one","two","three"); 

    Je crois que le point ici est que même si une collection est non modifiable, cela ne garantit pas qu’elle ne peut pas changer. Prenons par exemple une collection qui expulse des éléments s’ils sont trop anciens. Unmodifiable signifie simplement que l’object qui contient la référence ne peut pas le changer, pas qu’il ne peut pas changer. Un exemple vrai est la méthode Collections.unmodifiableList . Il renvoie une vue non modifiable d’une liste. La référence à la liste qui a été transmise à cette méthode est toujours modifiable et la liste peut donc être modifiée par tout détenteur de la référence transmise. Cela peut entraîner des exceptions de ConcurrentModificationExceptions et d’autres mauvaises choses.

    Immuable, cela signifie que la collection ne peut en aucun cas être modifiée.

    Deuxième question: une collection immuable ne signifie pas que les objects contenus dans la collection ne changeront pas, mais cette collection ne changera pas dans le nombre et la composition des objects qu’elle contient. En d’autres termes, la liste de références de la collection ne changera pas. Cela ne signifie pas que les composants internes de l’object référencé ne peuvent pas être modifiés.

    Pure4J prend en charge ce que vous recherchez, de deux manières.

    Tout d’abord, il fournit une annotation @ImmutableValue , de sorte que vous pouvez annoter une classe pour dire qu’elle est immuable. Il existe un plugin maven pour vous permettre de vérifier que votre code est réellement immuable (utilisation de la version final etc.).

    Deuxièmement, il fournit les collections persistantes de Clojure (avec des génériques ajoutés) et garantit que les éléments ajoutés aux collections sont immuables. Leur performance est apparemment très bonne. Les collections sont toutes immuables, mais implémentent des interfaces de collections java (et génériques) pour l’inspection. La mutation renvoie de nouvelles collections.

    Disclaimer: Je suis le développeur de cette