ventajas son que porque por objetos objeto mutables modificar los inmutables inmutable inmutabilidad clases java collections immutability

java - objetos - porque los string son inmutables



Colección inmutable vs inmodificable (6)

Básicamente, la colección no unModifiable es una vista, por lo que, de forma indirecta, podría ser ''modificada'' a partir de alguna otra referencia que sea modificable. Además, como es solo una vista de solo lectura de otra colección, cuando la colección de origen cambia, la colección unModificable siempre se presentará con los últimos valores.

Sin embargo, la colección immutable se puede tratar como una copia de solo lectura de otra colección y no se puede modificar. En este caso, cuando la colección fuente cambia, la Colección inmutable no refleja los cambios

Aquí hay un caso de prueba para visualizar esta diferencia.

@Test public void testList() { List<String> modifiableList = new ArrayList<String>(); modifiableList.add("a"); System.out.println("modifiableList:"+modifiableList); System.out.println("--"); //unModifiableList assertEquals(1, modifiableList.size()); List<String> unModifiableList=Collections.unmodifiableList( modifiableList); modifiableList.add("b"); boolean exceptionThrown=false; try { unModifiableList.add("b"); fail("add supported for unModifiableList!!"); } catch (UnsupportedOperationException e) { exceptionThrown=true; System.out.println("unModifiableList.add() not supported"); } assertTrue(exceptionThrown); System.out.println("modifiableList:"+modifiableList); System.out.println("unModifiableList:"+unModifiableList); assertEquals(2, modifiableList.size()); assertEquals(2, unModifiableList.size()); System.out.println("--"); //immutableList List<String> immutableList=Collections.unmodifiableList( new ArrayList<String>(modifiableList)); modifiableList.add("c"); exceptionThrown=false; try { immutableList.add("c"); fail("add supported for immutableList!!"); } catch (UnsupportedOperationException e) { exceptionThrown=true; System.out.println("immutableList.add() not supported"); } assertTrue(exceptionThrown); System.out.println("modifiableList:"+modifiableList); System.out.println("unModifiableList:"+unModifiableList); System.out.println("immutableList:"+immutableList); System.out.println("--"); assertEquals(3, modifiableList.size()); assertEquals(3, unModifiableList.size()); assertEquals(2, immutableList.size()); }

Salida

modifiableList:[a] -- unModifiableList.add() not supported modifiableList:[a, b] unModifiableList:[a, b] -- immutableList.add() not supported modifiableList:[a, b, c] unModifiableList:[a, b, c] immutableList:[a, b] --

Desde el Resumen del Marco de Colecciones :

Las colecciones que no admiten operaciones de modificación (como add , remove y clear ) se denominan no modificables . Las colecciones que no son modificables son modificables .

Las colecciones que además garantizan que ningún cambio en el objeto Collection será visible se denominan inmutables . Las colecciones que no son inmutables son mutables .

No puedo entender la distinción.
¿Cuál es la diferencia entre inmodificable e inmutable aquí?


Como se indicó anteriormente, no modificable no es inmutable porque una colección no modificable se puede modificar si, por ejemplo, una colección no modificable tiene una colección delegada subyacente a la que hace referencia otro objeto y ese objeto la cambia.

Respecto a lo inmutable, ni siquiera está bien definido. Sin embargo, generalmente significa que el objeto "no cambiará", pero que debería definirse recursivamente. Por ejemplo, puedo definir inmutables en clases cuyas variables de instancia son todas primitivas y cuyos métodos no contienen ningún argumento y primitivas de retorno. Los métodos luego permiten recursivamente que las variables de instancia sean inmutables y que todos los métodos contengan argumentos que son inmutables y que devuelven valores inmutables. Se debe garantizar que los métodos devuelvan el mismo valor a lo largo del tiempo.

Suponiendo que podamos hacer eso, también está seguro el hilo del concepto. Y es posible que te lleven a creer que lo inmutable (o no modificable en el tiempo) también implica la seguridad de los hilos. Sin embargo, ese no es el caso y ese es el punto principal que estoy haciendo aquí que aún no se ha notado en otras respuestas. Puedo construir un objeto inmutable que siempre devuelve los mismos resultados pero no es seguro para subprocesos. Ver esto supone que construyo una colección inmutable manteniendo adiciones y eliminaciones a lo largo del tiempo. Ahora la colección inmutable devuelve sus elementos observando la colección interna (que puede estar cambiando con el tiempo) y luego (internamente) agregando y eliminando los elementos que se agregaron o eliminaron después de la creación de la colección. Claramente, aunque la colección siempre devolvería los mismos elementos, no es segura para subprocesos simplemente porque nunca cambiará el valor.

Ahora podemos definir inmutables como objetos que son seguros para hilos y que nunca cambiarán. Existen pautas para crear clases inmutables que generalmente conducen a dichas clases, sin embargo, tenga en cuenta que puede haber formas de crear clases inmutables que requieren atención a la seguridad de subprocesos, por ejemplo, como se describe en el ejemplo de recopilación de "instantáneas" anterior.


Creo que la principal diferencia es que el propietario de una colección mutable podría querer proporcionar acceso a la colección a algún otro código, pero proporcionar ese acceso a través de una interfaz que no permita que el otro código modifique la colección (mientras se reserva esa capacidad) al código propietario). Por lo tanto, la colección no es inmutable, pero ciertos usuarios no pueden cambiar la colección.

El tutorial Java Collection Wrapper de Oracle tiene esto que decir (énfasis añadido):

Los envoltorios no modificables tienen dos usos principales, de la siguiente manera:

  • Para hacer una colección inmutable una vez que se ha construido. En este caso, es una buena práctica no mantener una referencia a la colección de respaldo. Esto absolutamente garantiza la inmutabilidad.
  • Permitir a ciertos clientes acceso de solo lectura a sus estructuras de datos. Mantiene una referencia a la colección de respaldo, pero distribuya una referencia a la envoltura. De esta forma, los clientes pueden mirar pero no modificar, mientras usted mantiene un acceso completo .

Si hablamos de JDK Unmodifiable* vs guava Immutable* , en realidad la diferencia también está en el rendimiento . Las colecciones inmutables pueden ser más rápidas y más eficientes en cuanto a la memoria si no son envoltorios en colecciones normales (las implementaciones JDK son envoltorios). Citando al equipo de guayaba :

El JDK proporciona métodos Collections.unmodifiableXXX, pero en nuestra opinión, estos pueden ser

<...>

  • ineficiente: las estructuras de datos aún tienen toda la sobrecarga de las colecciones mutables, incluidas las comprobaciones de modificación concurrentes, el espacio adicional en las tablas hash, etc.

Una colección no modificable a menudo es una envoltura alrededor de una colección modificable a la que otro código aún puede tener acceso . Entonces, si bien no puede realizar ningún cambio si solo tiene una referencia a la colección no modificable, no puede confiar en que el contenido no cambie.

Una colección inmutable garantiza que nada puede cambiar la colección más. Si envuelve una colección modificable, se asegura de que ningún otro código tenga acceso a esa colección modificable. Tenga en cuenta que aunque ningún código puede cambiar los objetos a los que la colección contiene referencias, los objetos en sí mismos pueden seguir siendo mutables: la creación de una colección inmutable de StringBuilder no "congela" de alguna manera esos objetos.

Básicamente, la diferencia radica en si otro código puede cambiar la colección que está detrás de usted.


para citar documentos Java, a diferencia de los contenedores de sincronización, que agregan funcionalidad a la colección envuelta, los contenedores no modificables quitan la funcionalidad. En particular, eliminan la capacidad de modificar la colección interceptando todas las operaciones que modificarían la colección y lanzando una UnsupportedOperationException .

Los envoltorios no modificables tienen dos usos principales, de la siguiente manera:

Para hacer una colección inmutable una vez que se ha construido. En este caso, es una buena práctica no mantener una referencia a la colección de respaldo. Esto absolutamente garantiza la inmutabilidad.

Permitir a ciertos clientes acceso de solo lectura a sus estructuras de datos. Mantiene una referencia a la colección de respaldo, pero distribuya una referencia a la envoltura. De esta forma, los clientes pueden mirar pero no modificar, mientras usted mantiene un acceso completo.

Esto realmente lo resume.