JavaRush /Blog Java /Random-ES /Inicialización de doble llave
Joysi
Nivel 41

Inicialización de doble llave

Publicado en el grupo Random-ES

1. Inicialización de doble llave

La inicialización mediante llaves dobles ( en lo sucesivo, inicialización con llaves dobles ) es una herramienta Java para crear colecciones como listas, conjuntos y mapas simultáneamente con su declaración.
Inicialización de doble llave - 1
Cuando necesita listas con elementos fijos, como una lista de productos o monedas admitidos, declarar la lista al mismo tiempo que la inicializa mejora la legibilidad del código. Es por eso que la inicialización con doble llave está ganando popularidad, ya que no existen otros métodos estándar para crear colecciones con inicialización simultánea en el código. Desafortunadamente, a diferencia de otros lenguajes de programación, Java no admite colecciones de literales. Debido a esta limitación, crear una Lista no modificable incluso con una pequeña cantidad de elementos nos obliga a escribir muchas líneas de código en forma de llamadas repetidas add()para agregar los elementos deseados con ajuste final:
List<Integer> list = new ArrayList<>();
list.add(2);
list.add(3);
list.add(5);
list.add(7);
List<Integer> unmodifiableList = Collections.unmodifiableList(list);
Esta es una descripción innecesariamente redundante que podría simplificarse. Completemos listas estáticas de la manera que más nos convenga, es decir, directamente en bloques estáticos durante la inicialización, que es en lo que Double bracenos ayudará la inicialización, permitiéndonos escribir todo en una línea:
List<Integer> list = Collections.unmodifiableList(new ArrayList<Integer>() {{
        add(2);
        add(3);
        add(5);
}});
De manera similar, Double bracela inicialización nos ayudará a completar valores y HashMap:
Map<Integer, String> intToString = new HashMap<Integer, String>(){{
         put(1, "one");
         put(2, "two");
         put(3, "three");
 }};
Todo parece muy elegante, pero tiene sus inconvenientes, que hacen que la inicialización de doble llave sea un antipatrón. Los veremos más a fondo en el próximo capítulo.

Pros y contras de la inicialización de doble llave.

DoubleLa inicialización de llaves utiliza la creación de una clase interna anónima . Lo que inicialmente está oculto en la superficie, sin embargo, Double bracela inicialización crea una clase con una mayor inicialización de su instancia cada vez que la usa. Además se utiliza una referencia oculta a esta clase privada, lo que nos puede llevar a posibles pérdidas de memoria. Tampoco puedes usar el operador fantasma para genéricos (operador diamante < >), ya que no podemos acceder al interior de una clase anónima.
(Del traductor: Una vez más con más detalle:
después del primero {, se crea una clase anónima interna, después del segundo, {la inicialización ocurre al crear una instancia de la clase, en la que tenemos acceso a los campos y métodos del externo ( relativo a la clase anónima).
Ventajas:
  1. Reducir líneas en el código
  2. Creación e inicialización en una sola expresión.
Desventajas:
  1. Creando una clase anónima oculta para ti.
  2. Lo cual nos cuesta costos adicionales por su instancia cada vez que la utilizamos.
  3. Cada vez que se crea una referencia oculta, lo que puede provocar pérdidas de memoria.
Veredicto: Debido a las desventajas anteriores y a la existencia de alternativas a la doble llave, la inicialización se considera un antipatrón en el mundo Java. salva al gatito

Alternativas a la inicialización de doble llave en Java

La buena noticia es que existen otras formas de lograr los mismos objetivos en Java. Podemos implementar en una línea de código la creación e inicialización de un ArrayList usando el constructor Copy de la clase Collection como se muestra a continuación:
List<Integer> list = Collections.unmodifiableList(new ArrayList<>(Arrays.asList(2, 3, 5)));
Arrays.asList()nos devolverá una lista de longitud fija pasada al ArrayListconstructor de la copia. Tenga en cuenta la diferencia entre las listas de longitud fija devueltas por Arrays.asList()y Collections.unmodifiableList(): no puede agregar ni eliminar elementos ArrayListde -, pero puede cambiar un elemento por índice usando set(), lo que no puede hacer con una lista devuelta por Collections.unmodifiableList(). Si quieres obtener una lista pequeña, esta es la mejor manera, aunque será menos transparente para Setotras colecciones, por lo que tendrás que crearla Listantes de crear Set-a. Pero esto sigue siendo mejor que la inicialización con doble llave, ya que en este caso no se crea una clase anónima interna adicional cada vez que se utiliza. Si estás ejecutando Java 8 tienes otro método alternativo. La API JDK 8 Stream le ayudará a crear pequeñas colecciones combinando Stream Factorymétodos de salida en una colección List:
List<String> list = Collections.unmodifiableList(Stream.of("abc", "bcd", "cde").collect(toList()));
En Setsu lugar, puede utilizar Collectors.toSet()el método Collectors.toList()que se muestra a continuación:
Set<String> set = Collections.unmodifiableSet(Stream.of("abc", "bcd", "cde").collect(toSet()));
Por cierto, Stream collectlos métodos no garantizan que las colecciones que generan estén protegidas contra cambios. En Java 8, las colecciones que devolvieron (como - ArrayList, HashSety HashMap) son bastante comunes (podemos cambiarlas), pero este hecho puede corregirse en futuras versiones de JDK. Eso es todo por ahora sobre Double bracela inicialización en Java. Esta plantilla es aceptable para pruebas y demostraciones, pero no lo suficientemente buena para uso en producción. Debido a sus desventajas inherentes, la inicialización de doble llave se ha convertido en un antipatrón en estos días, especialmente dadas las alternativas disponibles. Yo mismo todavía uso esta construcción para inicializar mapas estáticos y eso es todo. Porque Listprefiero crear Collectionscombinando con crear Array.asListen su constructor. Y si uso Java 8, un diseño que utiliza Stream API y collect(). Artículos relacionados: si disfrutó de este tutorial y desea obtener más información sobre los patrones, principios y mejores prácticas de programación de Java, es posible que también desee consultar los otros artículos de nuestro sitio . Lectura recomendada: si desea obtener más información sobre patrones y mejores prácticas, debe leer Programación efectiva de Joshua Bloch , ningún libro puede reemplazarlo. Y si ya domina Java y está buscando un libro sobre patrones de diseño, cuyo estilo de presentación humorístico sea interesante y fácil de leer, preste atención a “Head First”. Patrones de diseño" .
Del traductor: Proporcioné deliberadamente un enlace al libro original de Bloch, ya que su traducción al ruso no tuvo éxito (por ejemplo, Builder = constructor).
Traducción del artículo ¿Qué es la inicialización de doble llave en Java? Ejemplo antipatrón (publicado en octubre de 2015).
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION