Listas
doSomething ()
public static final, Lista UNSAFE_ZONES = Arrays.asList (
"África / El Cairo"
"África / Johannesburg"
"América / Anchorage"
...);
displayZones (UNSAFE_ZONES);
un método llamado displayZones (zonas Lista
lista inmutable
public static final, Lista TIME_ZONES = />
"África / El Cairo" ,
"África / Johannesburg"
"América / Anchorage"
...)) ;
gente siempre que aparezca la concurrencia con relación a las estructuras de datos inmutables, y la inmutabilidad es un regalo del cielo con respecto a la concurrencia. Puede pasar objetos inmutables y colecciones libremente entre cualquier número de hilos sin ningún bloqueo, la sincronización, copias de defensa, o la contención, que es una gran victoria tanto en términos de rendimiento y simplicidad. Pero a nivel del día a día, incluso con un solo hilo, el gran beneficio para este estilo de codificación es que no se preguntan si algo cambió su colección, ya que no es sólo posible.
Imagínese ahora que usted es el autor de displayZones () y que desea comunicar a las personas que utilizan su API que displayZones () nunca van a modificar la lista que se envía. Una forma de hacer esto es escribir un comentario en el JavaDoc como, «Yo nunca prometo que modificar su lista dentro displayZones ().» Para que esto sea efectivo, la gente tiene que 1. leer el JavaDoc y 2. Puedes creer. Si escribiera eso, ¿me creerías? Diablos, yo no me creo a mí mismo si yo lo escribí el mes pasado!
¿No sería agradable si el compilador lanzaría una advertencia de grasa bueno si alguien alguna vez actualizado displayZones () para modificar la lista que era enviado? Desde TIME_ZONES es una lista y displayZones () siempre se mostrará con el fin ordenado, puede declarar que tome una Iterable lugar de una lista: public void displayZones (zonas Iterable ) {...
Desde Iterable proporciona sólo sólo lectura métodos para recorrer en orden, la persona que llama sabe que incluso si te pasan una lista modificable, que no tiene que preocuparse por que cambiarlo, porque no se puede. No hay copias de defensa, no se preocupe. Pueden pasar cualquier colección, mutable o inmutable y no importará.
Todavía hay un beneficio para el paso de una colección inmutable. Si alguna vez cambia displayZones tomar un mutable ListaOtras Colecciones
<> s). Si alguien sabe una mejor manera breve / para hacer esto, por favor deje un comentario:
Inmutable Set
static final Establecer validModes = Collections.unmodifiableSet (
nueva HashSet <> (Arrays.asList (MODE_PREADD, MODE_ADD,
MODE_PREUPDATE, MODE_UPDATE)) );
EnumSet se prefiere para las enumeraciones, ya que se ejecuta más rápido y tiene una sintaxis más breve. EnumSets están ordenados de acuerdo a su «orden natural», que es el orden en que se declaran las constantes de enumeración.
static final privada Set ; validModes = Collections.unmodifiableSet (
EnumSet.of (Mode.PREADD, Mode.ADD, Mode.PREUPDATE, Mode.UPDATE));
Si está utilizando todos los valores de una enumeración en orden:
static final privada Set validModes = Collections.unmodifiableSet (
EnumSet.allOf (Modo . clase));
Inmutable Map
static final privada Mapa shortNameHash ;
{Mapa m = nueva HashMap <> () ;
m.put (SERVER_NAME_DEMO, "demo" );
m.put (SERVER_NAME_UAT, "UAT" );
m.put (SERVER_NAME_INTEGRATION, "integración" );
m.put (SERVER_NAME_DEV, "dev" );
shortNameHash = Collections.unmodifiableMap (m);
}
Es crítico en el ejemplo que el mapa Mapa temporal m estar en el ámbito dentro de un bloque dedicado de forma que pase fuera de alcance y no se puede acceder por cualquier cosa después de crear la versión inmutable de la misma. Mapa m permanece para siempre mutable, y un cierre léxico (bloque) es la forma más sencilla de mantener ningún tipo de código de acceso de usuario de mantener una referencia directa a la misma.
conversión de tipos
public enum implementos class="keyword">
DropDownItemInterface {...
público static final Lista ddiVals =
Collections.unmodifiableList (Arrays.asList (
valores (DropDownItemInterface []) ()));
Si intenta colar la lista resultante en su lugar, usted verá por qué me he molestado en señalar esto (y por qué tantas personas prefieren lenguajes dinámicos).
Efectividad
getShortName (Map m) , no hay manera eficaz de decir la persona que llama que este método no puede modificar el mapa se le pasa. Google Guava queda corta también en este caso debido a que su estructura de datos ImmutableMap hereda de mapa en lugar de al revés. Esto tiene que ser fijado en el nivel de la API de Java, o de lo contrario, la gente necesita para iniciar la importación de algunos nueva API de colecciones en vez de java.util.
Scala y Clojure ambos hacen todas sus colecciones inmutable por defecto. La versión mutable de cada tipo de colección es una subclase de la inmutable. En cualquier idioma, se podría decir getShortName (ImmutableMap m)
(o similar), y tiene los beneficios que he descrito con Iterable. Java podría hacer esto también, y me siento muy fuertemente que deberían. La razón por la Scala y Clojure colecciones pueden ser inmutables por defecto es que se implementan para permitir copias muy ligeros para hacer muy rápidamente. Las colecciones inmutables en idiomas todavía han add () y put () los métodos que contienen (o equivalente). Ellos sólo devuelven una colección totalmente nueva que incluye la modificación de la anterior. En una colección de hash de tabla basada, sólo el depósito de hash que se cambia aún necesita ser copiado a la nueva colección. Los otros cubos se pueden compartir porque la colección es inmutable! Java podría permitir que el mismo tipo de copias rápidas y poco profundas de las colecciones, pero tiene la bola y una cadena de 15 años de edad añadir ()
y put ()
métodos que devuelven un valor booleano en lugar de la colección subyacente. Debido a que este contamina el espacio de nombres para esos métodos, nuevos nombres de los métodos (como append ()
y anteponer ()
) tendrían que hacerse para todas las operaciones de modificación para que pudieran regresar una copia inmutable modificada de la colección original. Los viejos métodos podrían ser obsoletos con el tiempo. Esto podría llevar a cierta confusión a corto plazo, con gente que se pregunta por qué su colección inmutable no se ha cambiado por un append ()
llamada, pero yo personalmente creo que valdría la pena en el largo plazo.
A veces se necesita estructuras de datos mutables y por todos los medios, se utilicen. Pero cuando no lo hacen, prefieren inmutabilidad y usted dormirá mejor, piensan con más claridad, y escribir código más robusto.