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
ArrayList
es el método que escribió, ya que no necesita crear uno nuevoList
de ninguna manera:El problema es que hay que escribir bastante para referirse a esa
list
instancia.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
ArrayList
cual 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
List
lugar 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
places
es inmutable (intentar cambiarlo provocará unaUnsupportedOperationException
excepción).Para hacer una lista mutable que sea concreta
ArrayList
, puede crear unaArrayList
desde la lista inmutable:fuente
ArrayList
, sería mejor diseñar cambiar la declaración aList
. Especificar interfaces, no implementaciones.asList(...)
devuelve un tamaño fijoList
que explota en operaciones de mutación comoremove
yclear
, cosas que elList
contrato 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?remove
yclear
son 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 unList
que 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
var
palabra 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
List
respaldo de una matriz, por lo que no puede cambiar la longitud.Pero puedes llamar
List.set
, así que todavía es mutable .Puede
Arrays.asList
acortar 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+Enter
y seleccionaStatic import method...
.Sin embargo, no recomiendo acortar el
List.of
métodoof
, porque eso se vuelve confuso.List.of
ya es lo suficientemente corto y se lee bien.Usando
Stream
s¿Por qué tiene que ser un
List
?Con Java 8 o posterior, puede usar uno
Stream
que sea más flexible:Puedes concatenar
Stream
s:O puedes ir de un
Stream
a unList
:Pero preferiblemente, solo use el
Stream
sin 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
ArrayList
y agregar a ella después (¿por qué?), El usoo en Java 8 o anterior:
o usando
Stream
:Pero, de nuevo, es mejor usar
Stream
directamente en lugar de recopilarlo en aList
.Programa para interfaces, no para implementaciones
Dijiste que declaraste la lista como
ArrayList
en tu código, pero solo deberías hacerlo si estás usando algún miembroArrayList
que 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
,Collection
oList
), e inicializar con la aplicación específica (por ejemploArrayList
,LinkedList
oArrays.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
ArrayList
a unvoid method(...)
:Otro ejemplo sería siempre declarar una variable
InputStream
a pesar de que generalmente es aFileInputStream
o aBufferedInputStream
, porque un día pronto usted u otra persona querrán usar otro tipo deInputStream
.fuente
Arrays.asList
es 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.Arrays
como,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
List
es 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.ImmutableList
a 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
ArrayList
en 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.asList
mé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
enum
conjunto, que requeriría una nueva compilación si la lista necesita ser cambiada en el futuro.se convertiría:
Las
values
enumeraciones 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
Set
yMap
.fuente
fuente
Sí, con la ayuda de matrices, puede inicializar la lista de matrices en una línea,
fuente
Puedes usar
StickyList
desde 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::collect
fuente
En realidad, es posible hacerlo en una línea:
fuente