¿Existe una alternativa inmutable a las matrices primitivas en Java? Hacer una matriz primitiva en final
realidad no impide que uno haga algo como
final int[] array = new int[] {0, 1, 2, 3};
array[0] = 42;
Quiero que los elementos de la matriz sean inmutables.
int[]
ynew int[]
es MUCHO más fácil de escribir queList<Integer>
ynew ArrayList<Integer>
? XDRespuestas:
No con matrices primitivas. Deberá usar una Lista o alguna otra estructura de datos:
fuente
Arrays.asList
es inmodificable. docs.oracle.com/javase/7/docs/api/java/util/… "Devuelve una lista de tamaño fijo respaldada por la matriz especificada. (Cambios en la lista devuelta" escribir "en la matriz)"Arrays.asList()
hecho parece inmodificable en el sentido de que no puedesadd
o losremove
artículos devueltosjava.util.Arrays.ArrayList
(que no deben confundirse conjava.util.ArrayList
): estas operaciones simplemente no se implementan. ¿Quizás @mauhiz intenta decir esto? Pero, por supuesto, puede modificar elementos existentes conList<> aslist = Arrays.asList(...); aslist.set(index, element)
, por lo quejava.util.Arrays.ArrayList
ciertamente no es inmutable , QED agregó el comentario solo para enfatizar la diferencia entre el resultado deasList
y el normalArrayList
Mi recomendación es no utilizar una matriz o una
unmodifiableList
sino utilizar guayaba 's ImmutableList , que existe para este fin.fuente
Collections.unmodifiableList
suficiente para hacer que una Lista sea inmutable?Como otros han señalado, no puede tener matrices inmutables en Java.
Si necesita absolutamente un método que devuelva una matriz que no influya en la matriz original, deberá clonar la matriz cada vez:
Obviamente, esto es bastante costoso (ya que creará una copia completa cada vez que llame al getter), pero si no puede cambiar la interfaz (para usar un
List
por ejemplo) y no puede arriesgarse a que el cliente cambie sus componentes internos, entonces Puede ser necesario.Esta técnica se llama hacer una copia defensiva.
fuente
clone()
oArrays.copy()
aquí?Hay una forma de hacer una matriz inmutable en Java:
Las matrices con 0 elementos (obviamente) no se pueden mutar.
En realidad, esto puede ser útil si está utilizando el
List.toArray
método para convertirList
a en una matriz. Dado que incluso una matriz vacía ocupa algo de memoria, puede guardar esa asignación de memoria creando una matriz vacía constante y siempre pasándola altoArray
método. Ese método asignará una nueva matriz si la matriz que pasa no tiene suficiente espacio, pero si la tiene (la lista está vacía), devolverá la matriz que pasó, permitiéndole reutilizar esa matriz cada vez que llametoArray
a un vaciarList
.fuente
Otra respuesta
fuente
A partir de Java 9 puede usar
List.of(...)
, JavaDoc .Este método devuelve un inmutable
List
y es muy eficiente.fuente
Si necesita (por razones de rendimiento o para ahorrar memoria) 'int' nativo en lugar de 'java.lang.Integer', entonces probablemente deba escribir su propia clase de contenedor. Hay varias implementaciones de IntArray en la red, pero ninguna (encontré) era inmutable: Koders IntArray , Lucene IntArray . Probablemente hay otros.
fuente
Desde Guava 22, desde el paquete
com.google.common.primitives
puede usar tres nuevas clases, que tienen una huella de memoria más baja en comparación conImmutableList
.También tienen un constructor. Ejemplo:
o, si el tamaño se conoce en tiempo de compilación:
Esta es otra forma de obtener una vista inmutable de una matriz para primitivas Java.
fuente
No, esto no es posible. Sin embargo, uno podría hacer algo como esto:
Esto requiere el uso de contenedores, y es una Lista, no una matriz, pero es lo más cercano que obtendrá.
fuente
valueOf()
mensajes, el autoboxing se encargará de eso. TambiénArrays.asList(0, 2, 3, 4)
sería mucho más conciso.valueOf()
es utilizar el caché interno de objetos Integer para reducir el consumo de memoria / reciclaje.int
a unInteger
sin embargo; solo hay que tener cuidado al revés.En algunas situaciones, será más ligero usar este método estático de la biblioteca Google Guava:
List<Integer> Ints.asList(int... backingArray)
Ejemplos:
List<Integer> x1 = Ints.asList(0, 1, 2, 3)
List<Integer> x1 = Ints.asList(new int[] { 0, 1, 2, 3})
fuente
Si desea evitar la mutabilidad y el boxeo, no hay forma de salir de la caja. Pero puede crear una clase que contenga una matriz primitiva dentro y proporcione acceso de solo lectura a los elementos a través de métodos.
fuente
El método of (E ... elements) en Java9 se puede usar para crear una lista inmutable usando solo una línea:
El método anterior devuelve una lista inmutable que contiene un número arbitrario de elementos. Y agregar cualquier número entero a esta lista resultaría en una
java.lang.UnsupportedOperationException
excepción. Este método también acepta una sola matriz como argumento.fuente
Si bien es cierto que
Collections.unmodifiableList()
funciona, a veces puede tener una gran biblioteca con métodos ya definidos para devolver matrices (por ejemploString[]
). Para evitar romperlos, puede definir matrices auxiliares que almacenarán los valores:Probar:
No es perfecto, pero al menos tiene "matrices pseudoinmutables" (desde la perspectiva de la clase) y esto no romperá el código relacionado.
fuente
Bueno ... las matrices son útiles para pasar como constantes (si lo fueran) como parámetros de variantes.
fuente
int[]
, la persona que llama podría suponer que puede hacer lo que quiera con esa matriz sin afectar las partes internas de la API.