De la documentación de Java 1.6 Collection Framework :
Las colecciones que no admiten ninguna operación de modificación (como
add
,remove
yclear
) se denominan no modificables . [...] Las colecciones que además garantizan que ningún cambio en el objeto de la colección será visible se denominan inmutables .
El segundo criterio me confunde un poco. Dado que la primera colección no se puede modificar y suponiendo que la referencia de la colección original se haya eliminado, ¿a qué cambios se hace referencia en la segunda línea? ¿Se refiere a los cambios en los elementos contenidos en la colección, es decir, al estado de los elementos?
Segunda pregunta:
Para que una colección sea inmutable, ¿cómo se hace para proporcionar las garantías adicionales especificadas? Si el estado de un elemento de la colección es actualizado por un hilo, ¿es suficiente para la inmutabilidad que esas actualizaciones en el estado no sean visibles en el hilo que contiene la colección inmutable?
Para que un cobro sea inmutable, ¿cómo se hace para brindar las garantías adicionales especificadas?
fuente
newCol = oldCol.add("element")
producirá una nueva colección que es copia de la antigua con 1 elemento más, y todas las referencias a la mismaoldCol
seguirán apuntando a la misma colección antigua sin cambios.Respuestas:
Las colecciones no modificables suelen ser vistas de solo lectura (envoltorios) de otras colecciones. No puede agregarlos, eliminarlos o borrarlos, pero la colección subyacente puede cambiar.
Las colecciones inmutables no se pueden cambiar en absoluto, no envuelven otra colección, tienen sus propios elementos.
Aquí hay una cita de guayaba
ImmutableList
Entonces, básicamente, para obtener una colección inmutable de una mutable, debe copiar sus elementos a la nueva colección y no permitir todas las operaciones.
fuente
unmodifiableList
, el código que recibe solo una referencia a esa lista no podrá modificarla, pero cualquier código que tuviera una referencia a la lista original y pudiera modificarla antes de que se creara la envoltura seguirá siendo poder hacerlo después. Si el código que creó la lista original sabe lo que ha sucedido con cada referencia que ha existido a él, y sabe que ninguno de ellos caerá en manos de un código que pueda modificar la lista, entonces puede saber que la lista nunca será modificado. Sin embargo, si la referencia se recibió de un código externo ...unmodifiableList
, ni ningún código que lo use, sepa si la colección empaquetada podría cambiar o cómo.La diferencia es que no puede tener una referencia a una colección inmutable que permita cambios. Las colecciones inmodificables no son modificables a través de esa referencia. , pero algún otro objeto puede apuntar a los mismos datos a través de los cuales se puede cambiar.
p.ej
fuente
c1
es mutable (es decir, ni inmodificable ni inmutable ). noc2
es modificable : no se puede cambiar en sí mismo, pero si luego cambioc1
, ese cambio será visible enc2
.Esto se debe a que
c2
es simplemente un envoltorioc1
y no realmente una copia independiente. Guava proporciona laImmutableList
interfaz y algunas implementaciones. Estos funcionan creando una copia de la entrada (a menos que la entrada sea una colección inmutable por sí misma).Respecto a tu segunda pregunta:
La mutabilidad / inmutabilidad de una colección no depende de la mutabilidad / inmutabilidad de los objetos que contiene. La modificación de un objeto contenido en una colección no cuenta como una "modificación de la colección" para esta descripción. Por supuesto, si necesita una colección inmutable, generalmente también desea que contenga objetos inmutables.
fuente
c1
no se escapa" no es una consideración que se distinga en ninguna parte de la especificación. En mi opinión, si se puede usar la colección de una manera que hace que no sea inmutable, entonces usted debe siempre tener en cuenta que no inmutable.Collection.unmodifiableList()
no puede garantizar eso, porque no puede garantizar que su argumento no se escape. La guayabaImmutableList.of
siempre produce un inmutableList
, incluso si dejas escapar sus argumentos.Ahora java 9 tiene métodos de fábrica para lista inmutable, conjunto, mapa y entrada de mapa.
En Java SE 8 y versiones anteriores, podemos usar métodos de utilidad de la clase Colecciones como unmodifiableXXX para crear objetos de colección inmutables.
Sin embargo, estos métodos Collections.unmodifiableXXX son un enfoque muy tedioso y detallado. Para superar esas deficiencias, Oracle corp ha agregado un par de métodos de utilidad a las interfaces List, Set y Map.
Ahora en java 9: - Las interfaces List y Set tienen métodos "of ()" para crear una lista inmutable vacía o no vacía o objetos Set como se muestra a continuación:
Ejemplo de lista vacía
Ejemplo de lista no vacía
fuente
List.copyOf
ySet.copyOf
se han agregado que permiten crear una copia no modificable de una lista / conjunto, o devolver la colección dada si ya no es modificable, consulte JDK-8191517Creo que el punto aquí es que incluso si una colección no se puede modificar, eso no garantiza que no pueda cambiar. Tomemos, por ejemplo, una colección que desaloja elementos si son demasiado antiguos. No modificable solo significa que el objeto que contiene la referencia no puede cambiarlo, no que no pueda cambiar. Un verdadero ejemplo de esto es
Collections.unmodifiableList
método. Devuelve una vista no modificable de una lista. La referencia de la lista que se pasó a este método aún es modificable, por lo que cualquier titular de la referencia que se pasó puede modificar la lista. Esto puede resultar en ConcurrentModificationExceptions y otras cosas malas.Inmutable, significa que de ninguna manera se puede cambiar la colección.
Segunda pregunta: Una colección inmutable no significa que los objetos contenidos en la colección no cambiarán, solo que la colección no cambiará en el número y composición de los objetos que contiene. En otras palabras, la lista de referencias de la colección no cambiará. Eso no significa que las partes internas del objeto al que se hace referencia no puedan cambiar.
fuente
unmodifiableList
modificarse. Si quieres hacer este usoImmutableList
.Pure4J respalda lo que busca , de dos maneras.
Primero, proporciona una
@ImmutableValue
anotación, para que pueda anotar una clase para decir que es inmutable. Hay un complemento de Maven que le permite verificar que su código realmente sea inmutable (uso de,final
etc.).En segundo lugar, proporciona las colecciones persistentes de Clojure (con genéricos añadidos) y garantiza que los elementos añadidos a las colecciones sean inmutables. El rendimiento de estos es aparentemente bastante bueno. Las colecciones son inmutables, pero implementan interfaces de colecciones Java (y genéricos) para su inspección. Mutation devuelve nuevas colecciones.
Descargo de responsabilidad: soy el desarrollador de esto
fuente