Quería crear una lista de opciones para fines de prueba. Al principio, hice esto:
ArrayList<String> places = new ArrayList<String>();
places.add("Buenos Aires");
places.add("Córdoba");
places.add("La Plata");
Luego, refactoré el código de la siguiente manera:
ArrayList<String> places = new ArrayList<String>(
Arrays.asList("Buenos Aires", "Córdoba", "La Plata"));
¿Hay una mejor manera de hacer esto?
java
collections
arraylist
initialization
Macarse
fuente
fuente

ArrasyList<String> places = ["Buenos Aires", "Córdoba", "La Plata"]Respuestas:
En realidad, probablemente la "mejor" forma de inicializar
ArrayListes el método que escribió, ya que no necesita crear uno nuevoListde ninguna manera:El problema es que hay que escribir bastante para referirse a esa
listinstancia.Existen alternativas, como crear una clase interna anónima con un inicializador de instancia (también conocido como "inicialización de doble paréntesis"):
Sin embargo, no me gusta mucho ese método porque lo que termina es una subclase de la
ArrayListcual tiene un inicializador de instancia, y esa clase se crea solo para crear un objeto, eso me parece un poco exagerado.Lo que hubiera sido bueno fue que se aceptara la propuesta de Collection Literals para Project Coin (estaba programada para ser introducida en Java 7, pero tampoco es probable que forme parte de Java 8):
Desafortunadamente, no lo ayudará aquí, ya que inicializará un inmutable en
Listlugar de unArrayList, y además, aún no está disponible, si alguna vez lo estará.fuente
Sería más simple si simplemente lo declararas como
List: ¿tiene que ser una ArrayList?O si solo tiene un elemento:
Esto significaría que
placeses inmutable (intentar cambiarlo provocará unaUnsupportedOperationExceptionexcepción).Para hacer una lista mutable que sea concreta
ArrayList, puede crear unaArrayListdesde la lista inmutable:fuente
ArrayList, sería mejor diseñar cambiar la declaración aList. Especificar interfaces, no implementaciones.asList(...)devuelve un tamaño fijoListque explota en operaciones de mutación comoremoveyclear, cosas que elListcontrato afirma respaldar. Incluso si dejó la declaración comoList, debe usarlaList l = new ArrayList(asList(...))para obtener un objeto que no arroje excepciones OperationNotSupported. Principio de sustitución de Liskov alguien?removeyclearson operaciones opcionales enList, asíasList(...)que sigue el contrato. En ninguna parte el OP dice que necesita agregar más elementos más tarde, el ejemplo es solo unListque debe inicializarse con tres elementos.La respuesta simple
En Java 9 o posterior, después
List.of()se agregó:Con Java 10 o posterior, esto se puede acortar con la
varpalabra clave.Esto le dará un inmutable
List, por lo que no se puede cambiar.Que es lo que quieres en la mayoría de los casos donde lo estás rellenando.
Java 8 o anterior:
Esto le dará un
Listrespaldo de una matriz, por lo que no puede cambiar la longitud.Pero puedes llamar
List.set, así que todavía es mutable .Puede
Arrays.asListacortar aún más con una importación estática:La importación estática:
Lo que cualquier IDE moderno sugerirá y hará automáticamente por usted.
Por ejemplo, en IntelliJ IDEA, presiona
Alt+Entery seleccionaStatic import method....Sin embargo, no recomiendo acortar el
List.ofmétodoof, porque eso se vuelve confuso.List.ofya es lo suficientemente corto y se lee bien.Usando
Streams¿Por qué tiene que ser un
List?Con Java 8 o posterior, puede usar uno
Streamque sea más flexible:Puedes concatenar
Streams:O puedes ir de un
Streama unList:Pero preferiblemente, solo use el
Streamsin recogerlo aList.Si realmente necesitas un
java.util.ArrayList(Probablemente no.)
Para citar JEP 269 (el énfasis es mío):
Si desea tanto una rellenar previamente
ArrayListy agregar a ella después (¿por qué?), El usoo en Java 8 o anterior:
o usando
Stream:Pero, de nuevo, es mejor usar
Streamdirectamente en lugar de recopilarlo en aList.Programa para interfaces, no para implementaciones
Dijiste que declaraste la lista como
ArrayListen tu código, pero solo deberías hacerlo si estás usando algún miembroArrayListque no está enList.Lo que probablemente no estés haciendo.
Por lo general, sólo debe declarar variables por la interfaz más general que se va a utilizar (por ejemplo
Iterable,CollectionoList), e inicializar con la aplicación específica (por ejemploArrayList,LinkedListoArrays.asList()).De lo contrario, está limitando su código a ese tipo específico, y será más difícil cambiarlo cuando lo desee.
Por ejemplo, si está pasando un
ArrayLista unvoid method(...):Otro ejemplo sería siempre declarar una variable
InputStreama pesar de que generalmente es aFileInputStreamo aBufferedInputStream, porque un día pronto usted u otra persona querrán usar otro tipo deInputStream.fuente
Arrays.asListes un método estático. Ver docs.oracle.com/javase/1.5.0/docs/guide/language/…Si necesita una lista simple de tamaño 1:
Si necesita una lista de varios objetos:
fuente
Con guayaba puedes escribir:
En Guava también hay otros constructores estáticos útiles. Puedes leer sobre ellos aquí .
fuente
java.util.Arrayscomo,List<String> names = Arrays.asList("Beckah", "Sam", "Michael");Los literales de colección no llegaron a Java 8, pero es posible usar Stream API para inicializar una lista en una línea bastante larga:
Si necesita asegurarse de que su
Listes unArrayList:fuente
Con java-9y más arriba, como se sugiere en JEP 269: Convenience Factory Methods for Collections , esto podría lograrse usando literales de colección ahora con -
También se aplicaría un enfoque similar
Map:que es similar a la propuesta de Collection Literals según lo indicado por @coobird. Más aclarado en el JEP también:
Alternativas
Relacionado: ¿Cuál es el punto de los métodos de fábrica de conveniencia sobrecargados para colecciones en Java 9
fuente
fuente
Collections.unmodifiableList(Arrays.asList("Buenos Aires", "Córdoba", "La Plata"))que sucedeunmodifiableList(asList("Buenos Aires", "Córdoba", "La Plata"))con las importaciones estáticas. No necesita Google Collections para esto.ImmutableLista otros métodos que toman unList, y luego has perdido esa documentación de todos modos.Podrías crear un método de fábrica:
Pero no es mucho mejor que tu primera refactorización.
Para una mayor flexibilidad, puede ser genérico:
fuente
En Java 9, podemos inicializar fácilmente
ArrayListen una sola línea:o
Este nuevo enfoque de Java 9 tiene muchas ventajas sobre los anteriores:
Vea esta publicación para más detalles -> ¿Cuál es la diferencia entre List.of y Arrays.asList?
fuente
La forma más compacta de hacer esto es:
fuente
Simplemente use el siguiente código de la siguiente manera.
fuente
Con Eclipse Collections puede escribir lo siguiente:
También puede ser más específico sobre los tipos y si son mutables o inmutables.
También puede hacer lo mismo con Conjuntos y Bolsas:
Nota: Soy un committer para Eclipse Collections.
fuente
Aquí hay otra forma:
fuente
(Debería ser un comentario, pero demasiado largo, así que nueva respuesta). Como otros han mencionado, el
Arrays.asListmétodo es de tamaño fijo, pero ese no es el único problema con él. Tampoco maneja la herencia muy bien. Por ejemplo, suponga que tiene lo siguiente:Lo anterior genera un error de compilación porque
List<B>(que es lo que devuelve Arrays.asList) no es una subclase deList<A>, aunque puede agregar Objetos de tipo B a unList<A>objeto. Para evitar esto, debe hacer algo como:Esta es probablemente la mejor manera de hacerlo, especialmente. si necesita una lista ilimitada o necesita usar la herencia.
fuente
Puede usar las siguientes declaraciones:
Fragmento de código:
fuente
letters = Arrays.asList(new String[]{"A", "B", "C"});Como dijo Tom :
Pero como se quejó de querer una ArrayList, primero debe saber que ArrayList es una subclase de List y simplemente puede agregar esta línea:
Sin embargo, eso podría hacer que te quejes de "rendimiento".
En ese caso, no tiene sentido para mí, por qué, dado que su lista está predefinida, no se definió como una matriz (ya que el tamaño se conoce en el momento de la inicialización). Y si esa es una opción para ti:
En caso de que no le importen las pequeñas diferencias de rendimiento, también puede copiar una matriz a una ArrayList de manera muy simple:
Está bien, pero en el futuro necesita un poco más que el nombre del lugar, también necesita un código de país. Asumiendo que esta sigue siendo una lista predefinida que nunca cambiará durante el tiempo de ejecución, entonces es apropiado usar un
enumconjunto, que requeriría una nueva compilación si la lista necesita ser cambiada en el futuro.se convertiría:
Las
valuesenumeraciones tienen un método estático que devuelve una matriz que contiene todos los valores de la enumeración en el orden en que se declaran, por ejemplo:En ese caso, supongo que no necesitarías tu ArrayList.
PS Randyaa demostró otra forma agradable usando el método de utilidad estática Collections.addAll .
fuente
Java 9 tiene el siguiente método para crear una lista inmutable :
que se adapta fácilmente para crear una lista mutable, si es necesario:
Métodos similares están disponibles para
SetyMap.fuente
fuente
Sí, con la ayuda de matrices, puede inicializar la lista de matrices en una línea,
fuente
Puedes usar
StickyListdesde Cactoos :fuente
Pruebe con esta línea de código:
fuente
En Java, no puedes hacer
Como se señaló, necesitaría hacer una inicialización de doble llave:
Pero esto puede obligarlo a agregar una anotación
@SuppressWarnings("serial")o generar un UUID en serie que es molesto. Además, la mayoría de los formateadores de código lo desenvolverán en múltiples declaraciones / líneas.Alternativamente puedes hacer
pero entonces es posible que desee hacer una
@SuppressWarnings("unchecked").También según javadoc, deberías poder hacer esto:
Pero no puedo hacer que se compile con JDK 1.6.
fuente
¡Si necesita tener una lista de un artículo !
Colecciones es del paquete java.util .
fuente
La mejor manera de hacerlo:
Simplemente cree una función que pueda tener tantos elementos como desee y llámela para agregarlos en una línea.
fuente
Object.Aquí está el código de AbacusUtil
Declaración: Soy el desarrollador de AbacusUtil.
fuente
Para mí, Arrays.asList () es el mejor y conveniente. Siempre me gusta inicializar de esa manera. Si es un principiante en Java Collections, me gustaría que consulte la inicialización de ArrayList
fuente
add()métodos?¿Por qué no hacer una función de utilidad simple que haga esto?
"
ll" significa "lista literal".fuente
Curiosamente, no aparece una línea con el otro método sobrecargado
Stream::collectfuente
En realidad, es posible hacerlo en una línea:
fuente