Lista.de() o Colecciones.emptyList()

5 minutos de lectura

avatar de usuario
Sormuras

Como un caso especial de List.of(…) o Collections.unmodifiableList() – ¿cuál es la forma preferida de Java 9 de apuntar a un vacío y inmutable ¿lista?

Seguir escribiendo

Collections.emptyList();

o cambiar a

List.of();

  • Votante(s) cercano(s): Casi voté principalmente por la opinión, pero hay dos razones objetivas para preferir emptyList() y ninguno que se me ocurra preferir List.of()que parece hacer este tema.

    – chrylis -cautelosamente optimista-

    08/09/2016 a las 21:36

avatar de usuario
chrylis -cautelosamente optimista-

Collections.emptyList() no necesita crear un nuevo objeto para cada llamada; es tipico, como en OpenJDKpara simplemente devolver el singleton EMPTY_LIST objeto. Además, es más claro que tiene la intención de significar una lista vacía en lugar de haber olvidado completar un marcador de posición.

Usar emptyList(); es más rápido (hasta el nivel de destino de Java 1.9) y más legible.

  • @Andreas En realidad, no importa; todavía está creando un nuevo marcador de posición vacío.

    – chrylis -cautelosamente optimista-

    08/09/2016 a las 21:54

  • @Andreas No hay una razón inherente List.of() no podía devolver la misma instancia cada vez. Simplemente no se ha implementado todavía. Ver JDK-8156079. Dicho esto, la compensación no siempre es obvia. El uso de una instancia en caché probablemente ahorra memoria en general, pero también evita que el JIT realice ciertas optimizaciones. Eso ciertamente sucede con el caché de autoboxing. La razón que List.of() no llama Collections.emptyList() es que este último tiene una forma de serie bien definida que no se puede cambiar por razones de compatibilidad. El nuevo…

    – Marcas de Stuart

    28/09/2016 a las 23:15

  • @Sormuras … las fábricas de colecciones comparten un formato de serie común (un proxy de serialización) que facilitará el cambio de la estructura interna si queremos hacerlo en el futuro. También, emptyList() tiene un comportamiento un poco más laxo cuando se llama a los métodos mutadores. Por ejemplo, emptyList().addAll(emptyList()) es un no-op, pero List.of().addAll(emptyList()) lanza UnsupportedOperationException.

    – Marcas de Stuart

    28/09/2016 a las 23:22

  • he arreglado JDK-8156079 para que en JDK 9 acceso anticipado compilación 144 y posteriores, List.of(), Set.of()y Map.of() use singletons para instancias vacías.

    – Marcas de Stuart

    30 de noviembre de 2016 a las 14:54

  • emptyList() no es más rápido y List.of() “tampoco necesita crear un nuevo objeto para cada llamada”. La respuesta está desactualizada.

    – usuario1803551

    7 oct 2017 a las 11:44

avatar de usuario
usuario1803551

¿Cuál es la forma preferida de Java 9 de apuntar a una lista vacía e inmutable?

La diferencia es bastante sutil, por lo que “preferido” depende de lo que quieras lograr. Algunas diferencias de comportamiento:

  • List.of lanzará una excepción en contains(null) invocaciones
  • Puedes deserializar emptyList() en JDK 8 y anteriores, pero no List.of.

En términos o transmitiendo que desea una lista vacía, emptyList() podría verse mejor, pero esto es solo una convención temporal. Si los desarrolladores comienzan a usar List.of() (que es mucho más corto que Collections.emptyList()) entonces se convertirá en una forma conocida y aceptada, es simplemente nueva. Si lo piensas bien, hay algunas construcciones que usamos que no siempre transmiten lo que hacen por sí mismas, pero nos acostumbramos a ellas.

Así que no hay una forma estrictamente preferida. Si el comportamiento no importa usa lo que quieras.

  • Esta pregunta y su respuesta aceptada (comentada por el autor) tienen más de 1 año.

    – Sormuras

    7 oct 2017 a las 11:47

  • @Sormuras Soy muy consciente, ¿entonces? La gente quiere ver información actualizada cuando lee una pregunta. Las preguntas no caducan en este sitio, se actualizan con nuevas respuestas cada vez que hay una nueva forma de resolver el problema en la pregunta.

    – usuario1803551

    7 oct 2017 a las 11:50


  • Me parece bien. Su otro comentario debajo de la respuesta aceptada estaba oculto detrás de un enlace “mostrar más”.

    – Sormuras

    7 oct 2017 a las 11:54

  • @Sormuras: como se indica explícitamente: “Aceptar una respuesta no pretende ser una declaración definitiva y final que indique que la pregunta ahora ha sido respondida perfectamente.”… puede aceptar una respuesta más nueva si encaja mejor o si la más antigua está desactualizada, por cierto.

    – Holger

    12 de octubre de 2017 a las 6:46

  • los contains(null) bit es bastante relevante… Constructores para objetos inmutables a los que también les gusta null la seguridad a menudo hará un contains(null) verifique las colecciones pasadas, para garantizar a sus usuarios que no encontrarán null al mirar a través de una colección proporcionada. Cuando se creó una colección con List.of esto arroja un NPE, realmente molesto. los null verificar en el constructor ahora tiene que ser algo en las líneas de collection.stream().filter(Objects::isNull).findAny().isPresent()

    – juan16384

    21 de abril de 2019 a las 12:16


  1. emptyList() crea una nueva instancia de lista vacía sólo una vez
  2. no hay diferencia en Legibilidad: quizás List.of() es más corto que Collections.emptyList() pero puedes usar una importación estática como import static java.util.Collections.emptyList; y luego escribir solo emptyList()

  • De hecho, lo hice durante mucho tiempo, y algunos podrían argumentar que puedes hacer lo mismo con import static java.util.List.of; aunque eso es mucho menos legible… ¡gracias!

    – maxxyme

    8 abr a las 12:55

A partir de JDK 11, si observa el código fuente, verá que List.of()utiliza una lista vacía inicializada una sola vez, similar a Collections.emptyList(). Entonces, prefiero usar List.of() porque:

  • Es una API más reciente. Entonces, creo que si los mantenedores de Java estuvieran satisfechos con las formas anteriores, no agregarían una nueva API.
  • Es más conciso.
  • Si utiliza List.of(E... elements) (y deberías) para listas no vacías, puede usar List.of() para los vacíos y disfrute de una apariencia unificada y elimine la mayoría de los métodos de fábrica en Colecciones API.

¿Ha sido útil esta solución?