2 Unmodifiable Collections¶
Unmodifiable Collection¶
Una unmodifiable collection es un wrapper de sólo lectura sobre otra colección existente. Estos wrappers no permiten realizar a través de ellos las operaciones de agregar o eliminar en la colección. Sin embargo, la colección original que envuelve sí que puede ser modificada directamente y los cambios se verán reflejados en la versión inmodificable, e incluso podemos establecer null
como elemento.
La clase Collections
proporciona una serie de métodos estáticos para crear unmodified collections a partir de distintos tipos de colecciones, como por ejemplo Collections.unmodifiableCollection(collection)
, Collections.unmodifiableList(list)
, Collections.unmodifiableMap(map)
o Collections.unmodifiableSet(set)
.
Veamos un ejemplo:
List<String> mutableList = new ArrayList<>(Arrays.asList("C", "C++", "Java"));
List<String> unmodifiableList = Collections.unmodifiableList(mutableList);
// Any attempt to modify the unmodifiableList will throw UnsupportedOperationException
try {
unmodifiableList.add("Python");
}
catch (UnsupportedOperationException ex) {
System.out.println("java.lang.UnsupportedOperationException");
}
// Any changes made to the original list will be reflected back in the unmodifiable list
mutableList.add("Go");
// You can use null as an element of the list
mutableList.add(null);
System.out.println(unmodifiableList);
Otro ejemplo de colección inmodificable (parcialmente) es la lista retornada por el método estático Arrays.asList()
, que retorna una lista que actúa como wrapper sobre un array. Dado que lo arrays no pueden cambiar su tamaño, no es posible añadir o eliminar elementos en la lista retornada por este método, lanzándose la excepción UnsupportedOperationException
. Sin embargo, sí que es posible modificar el valor de un elemento de la lista usando el método set(index, element)
o modificando el array original.
Veamos un ejemplo:
String[] lang = new String[]{"C", "C++", "Java"};
List<String> fixedLengthList = Arrays.asList(lang);
try {
// any add or remove operation on the list will result in
// an UnsupportedOperationException
fixedLengthList.add("Python");
System.out.println("List : " + fixedLengthList);
} catch (UnsupportedOperationException ex) {
System.out.println("java.lang.UnsupportedOperationException");
}
// List can be modified by calling set() method
fixedLengthList.set(1, "Go");
// Any changes made to the original array will be reflected in the list
lang[2] = "JS";
// You can use null as an element of the list
lang[2] = null;
System.out.println("Array : " + Arrays.toString(lang));
Debemos tener en cuenta que si una colección no es modificable podemos decir que es thread-safe, ya que los distintos hilos no podrán modificarla y por tanto no podrán crearse conflictos.