Inicialización de una ArrayList en una línea

Quiero crear una lista de opciones para fines de prueba. Al principio, hice esto:

ArrayList places = new ArrayList(); places.add("Buenos Aires"); places.add("cordova"); places.add("La Plata"); 

Luego refactoré el código de la siguiente manera:

 ArrayList places = new ArrayList( Arrays.asList("Buenos Aires", "cordova", "La Plata")); 

¿Hay una mejor manera de hacer esto?

En realidad, probablemente la “mejor” manera de inicializar ArrayList es el método que escribió, ya que no necesita crear una nueva List de ninguna manera:

 ArrayList list = new ArrayList(); list.add("A"); list.add("B"); list.add("C"); 

El problema es que se requiere bastante tipeo para referirse a esa instancia de list .

Hay alternativas, como crear una clase interna anónima con un inicializador de instancia (también conocido como “inicialización de llave doble”):

 ArrayList list = new ArrayList() {{ add("A"); add("B"); add("C"); }}; 

Sin embargo, no soy muy aficionado a ese método porque con lo que terminas es con una subclase de ArrayList que 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 agradable fue que se aceptara la propuesta de Collection Literals para Project Coin (estaba previsto que se introdujera en Java 7, pero tampoco es probable que sea parte de Java 8):

 List list = ["A", "B", "C"]; 

Desafortunadamente no te ayudará aquí, ya que inicializará una List inmutable en lugar de una List de ArrayList , y además, aún no está disponible, si alguna vez lo será.

Sería más sencillo si solo declararas como una List : ¿tiene que ser una lista de arreglos?

 List places = Arrays.asList("Buenos Aires", "cordova", "La Plata"); 

O si solo tiene un elemento:

 List places = Collections.singletonList("Buenos Aires"); 

Esto significaría que los places son inmutables (intentar cambiarlos provocará una excepción UnsupportedOperationException ).

Para crear una lista mutable que sea una ArrayList concreta, puede crear una ArrayList partir de la lista inmutable:

 ArrayList places = new ArrayList<>(Arrays.asList("Buenos Aires", "Córdoba", "La Plata")); 

La respuesta simple

En Java 8 o anterior:

 List strings = Arrays.asList("foo", "bar", "baz"); 

Esto le dará una List respaldada por la matriz, por lo que no puede cambiar la longitud.
Pero puede llamar a List.set , por lo que sigue siendo mutable.


En Java 9:

 List strings = List.of("foo", "bar", "baz"); 

Esto le dará una List inmutable, por lo que no se puede cambiar.
Que es lo que quieres en la mayoría de los casos donde lo estás prepoblando.


La respuesta más corta

Puedes hacer que Arrays.asList aún más corto con una importación estática:

 List strings = asList("foo", "bar", "baz"); 

La importación estática:

 import static java.util.Arrays.asList; 

Lo que cualquier IDE moderno sugerirá y automáticamente hará por usted.
Por ejemplo, en IntelliJ IDEA, presione Alt+Enter y seleccione Static import method...


Sin embargo, no recomiendo acortar el método de la List.of de Java 9, porque tener solo se vuelve confuso.
List.of ya es lo suficientemente corto y se lee bien.


Usando Stream s

¿Por qué tiene que ser una List ?
Con Java 8 o posterior puede usar un Stream que sea más flexible:

 Stream strings = Stream.of("foo", "bar", "baz"); 

Puede concatenar Stream s:

 Stream strings = Stream.concat(Stream.of("foo", "bar"), Stream.of("baz", "qux")); 

O puede pasar de una Stream a una List :

 List strings = Stream.of("foo", "bar", "baz").collect(toList()); 

Pero preferiblemente, solo use Stream sin recostackrlo en una List .


Si realmente necesitas específicamente un java.util.ArrayList

(Probablemente no.)
Para citar JEP 269 (el énfasis es mío):

Hay un pequeño conjunto de casos de uso para inicializar una instancia de colección mutable con un conjunto predefinido de valores. Por lo general, es preferible tener esos valores predefinidos en una colección inmutable, y luego inicializar la colección mutable a través de un constructor de copia.


Si desea rellenar una ArrayList y agregarla luego (¿por qué?), Use

 List strings = new ArrayList<>(asList("foo", "bar", "baz")); 

o en Java 9:

 List strings = new ArrayList<>(List.of("foo", "bar", "baz")); 

o usando Stream :

 List strings = Stream.of("foo", "bar", "baz") .collect(toCollection(ArrayList::new)); 

Pero, de nuevo, es mejor usar Stream directamente en lugar de recostackrlo en una List .


Progtwig a interfaces, no a implementaciones

Dijiste que declaraste la lista como ArrayList en tu código, pero solo deberías hacerlo si estás usando algún miembro de ArrayList que no esté en la List .

Lo que probablemente no estés haciendo.

Por lo general, solo debe declarar las variables por la interfaz más general que vaya a utilizar (por ejemplo, Iterable , Collection o List ) e inicializarlas con la implementación específica (por ejemplo, ArrayList , LinkedList o Arrays.asList() ).

De lo contrario, estás limitando tu código a ese tipo específico, y será más difícil cambiarlo cuando quieras.

Por ejemplo:

 // Iterable if you just need iteration, for (String s : strings): Iterable strings = new ArrayList<>(); // Collection if you also need .size() or .stream(): Collection strings = new ArrayList<>(); // List if you also need .get(index): List strings = new ArrayList<>(); // Don't declare a specific list implementation // unless you're sure you need it: ArrayList strings = new ArrayList<>(); // You don't need ArrayList 

Otro ejemplo sería siempre declarar a la variable como un InputStream a pesar de que generalmente es un FileInputStream o un BufferedInputStream , porque un día pronto usted u otra persona querrá usar algún otro tipo de InputStream .

Si necesita una lista simple de tamaño 1:

 List strings = new ArrayList(Collections.singletonList("A")); 

Si necesita una lista de varios objetos:

 List strings = new ArrayList(); Collections.addAll(strings,"A","B","C","D"); 

Con Guava puedes escribir:

 ArrayList places = Lists.newArrayList("Buenos Aires", "cordova", "La Plata"); 

En Guava también hay otros constructores estáticos útiles. Puedes leer sobre ellos aquí .

Los literales de colección no llegaron a Java 8, pero es posible usar Stream API para inicializar una lista en una sola línea larga:

 List places = Stream.of("Buenos Aires", "cordova", "La Plata").collect(Collectors.toList()); 

Si necesita asegurarse de que su List es una ArrayList :

 ArrayList places = Stream.of("Buenos Aires", "cordova", "La Plata").collect(Collectors.toCollection(ArrayList::new)); 
 import com.google.common.collect.ImmutableList; .... List places = ImmutableList.of("Buenos Aires", "cordova", "La Plata"); 

Podrías crear un método de fábrica:

 public static ArrayList createArrayList(String ... elements) { ArrayList list = new ArrayList(); for (String element : elements) { list.add(element); } return list; } .... ArrayList places = createArrayList( "São Paulo", "Rio de Janeiro", "Brasília"); 

Pero no es mucho mejor que tu primera refactorización.

Para una mayor flexibilidad, puede ser genérico:

 public static  ArrayList createArrayList(T ... elements) { ArrayList list = new ArrayList(); for (T element : elements) { list.add(element); } return list; } 

Con Java 9 , como se sugiere en JDK Enhancement Proposal – 269 , esto podría lograrse utilizando literales de colección ahora como:

 List list = List.of("A", "B", "C"); Set set = Set.of("A", "B", "C"); 

También un enfoque similar se aplicaría a Map también –

 Map map = Map.of("k1", "v1", "k2", "v2", "k3", "v3") 

que es similar a la propuesta de Collection Literals según lo indicado por @coobird también. También se aclaró en el documento JEP:


Alternativas

Los cambios de idioma se han considerado varias veces y se han rechazado:

Proyecto de propuesta de monedas, 29 de marzo de 2009

Proyecto Coin Proposal, 30 de marzo de 2009

Discusión JEP 186 sobre lambda-dev, enero-marzo de 2014

Las propuestas de idioma se reservaron con preferencia a una propuesta basada en la biblioteca, tal como se resume en este mensaje.

Lectura encadenada sobre el mismo ~> ¿Cuál es el punto de los Métodos Convenience Factory sobrecargados?

En Java 9 podemos inicializar fácilmente una ArrayList en una sola línea:

 List places = List.of("Buenos Aires", "cordova", "La Plata"); 

o

 List places = new ArrayList<>(List.of("Buenos Aires", "Córdoba", "La Plata")); 

Este nuevo enfoque de Java 9 tiene muchas ventajas sobre los anteriores:

  1. Eficiencia espacial
  2. Inmutabilidad
  3. A salvo de amenazas

Consulte esta publicación para obtener más información:> ¿Cuál es la diferencia entre List.of y Arrays.asList?

La forma más compacta de hacer esto es:

 Double array[] = { 1.0, 2.0, 3.0}; List list = Arrays.asList(array); 

Con Eclipse Collections (anteriormente GS Collections ), puede escribir lo siguiente:

 List list = Lists.mutable.with("Buenos Aires", "cordova", "La Plata"); 

También puede ser más específico sobre los tipos y si son Mutables o Inmutables.

 MutableList mList = Lists.mutable.with("Buenos Aires", "cordova", "La Plata"); ImmutableList iList = Lists.immutable.with("Buenos Aires", "cordova", "La Plata"); 

También puede hacer lo mismo con Conjuntos y bolsos:

 Set set = Sets.mutable.with("Buenos Aires", "cordova", "La Plata"); MutableSet mSet = Sets.mutable.with("Buenos Aires", "cordova", "La Plata"); ImmutableSet iSet = Sets.immutable.with("Buenos Aires", "cordova", "La Plata"); Bag bag = Bags.mutable.with("Buenos Aires", "cordova", "La Plata"); MutableBag mBag = Bags.mutable.with("Buenos Aires", "cordova", "La Plata"); ImmutableBag iBag = Bags.immutable.with("Buenos Aires", "cordova", "La Plata"); 

Nota: soy un committer para las colecciones de Eclipse.

Simplemente use el siguiente código de la siguiente manera.

 List list = new ArrayList() {{ add("A"); add("B"); add("C"); }}; 

Aquí hay otra manera:

 List values = Stream.of("One", "Two").collect(Collectors.toList()); 

Puedes usar las siguientes declaraciones:

Fragmento de código:

 String [] arr = {"Sharlock", "Homes", "Watson"}; List names = Arrays.asList(arr); 

(Debería ser un comentario, pero demasiado largo, tan nueva respuesta). Como otros han mencionado, el método Arrays.asList es de tamaño fijo, pero ese no es el único problema. Tampoco maneja la herencia muy bien. Por ejemplo, supongamos que tienes lo siguiente:

 class A{} class B extends A{} public List getAList(){ return Arrays.asList(new B()); } 

Lo anterior da como resultado un error de comstackción, porque List (que es lo que Arrays.asList devuelve) no es una subclase de List , aunque puede agregar Objects of type B a un objeto List . Para evitar esto, debes hacer algo como:

 new ArrayList(Arrays.asList(b1, b2, b3)) 

Esta es probablemente la mejor forma de hacerlo, especialmente si necesita una lista ilimitada o necesita usar herencia.

Como Tom dijo :

 List places = Arrays.asList("Buenos Aires", "cordova", "La Plata"); 

Pero como usted se quejó de querer una ArrayList, primero debe saber que ArrayList es una subclase de List y simplemente puede agregar esta línea:

 ArrayList myPlaces = new ArrayList(places); 

Aunque, eso podría hacerte quejarse de ‘rendimiento’.

En ese caso, no tiene sentido para mí, porque su lista está predefinida y 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:

 String[] places = {"Buenos Aires", "cordova", "La Plata"}; 

En caso de que no le interesen las diferencias de rendimiento menores, también puede copiar una matriz a una ArrayList muy simplemente:

 ArrayList myPlaces = new ArrayList(Arrays.asList(places)); 

Está bien, pero en el futuro necesitas un poco más que solo el nombre del lugar, también necesitas un código de país. Asumiendo que esto sigue siendo una lista predefinida que nunca cambiará durante el tiempo de ejecución, entonces es apropiado usar un conjunto de enum , lo que requeriría una recomstackción si la lista necesita ser cambiada en el futuro.

 enum Places {BUENOS_AIRES, CORDOBA, LA_PLATA} 

se convertiría:

 enum Places { BUENOS_AIRES("Buenos Aires",123), CORDOBA("cordova",456), LA_PLATA("La Plata",789); String name; int code; Places(String name, int code) { this.name=name; this.code=code; } } 

Enum tiene un método de values estáticos que devuelve una matriz que contiene todos los valores de la enumeración en el orden en que se declaran, por ejemplo:

 for (Places p:Places.values()) { System.out.printf("The place %s has code %d%n", p.name, p.code); } 

En ese caso, supongo que no necesitarías tu ArrayList.

PS Randyaa demostró otra manera agradable de usar el método de utilidad estática Collections.addAll .

Java 9 tiene el siguiente método para crear una lista inmutable :

 List places = List.of("Buenos Aires", "cordova", "La Plata"); 

que se adapta fácilmente para crear una lista mutable, si es necesario:

 List places = new ArrayList<>(List.of("Buenos Aires", "Córdoba", "La Plata")); 

Métodos similares están disponibles para Set y Map .

 List names = Arrays.asList("2","@2234","21","11"); 

Puede usar StickyList de Cactoos :

 List names = new StickyList<>( "Scott Fitzgerald", "Fyodor Dostoyevsky" ); 

Pruebe con esta línea de código:

 Collections.singletonList(provider) 

Sí, con la ayuda de Arrays puedes inicializar la lista de arreglos en una línea,

 List strlist= Arrays.asList("aaa", "bbb", "ccc"); 

En Java, no puedes hacer

 ArrayList places = new ArrayList( Arrays.asList("Buenos Aires", "cordova", "La Plata")); 

Como se señaló, necesitarías hacer una inicialización con doble llave:

 List places = new ArrayList() {{ add("x"); add("y"); }}; 

Pero esto puede forzarlo 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 desenvolverán eso en múltiples declaraciones / líneas.

Alternativamente puedes hacer

 List places = Arrays.asList(new String[] {"x", "y" }); 

pero luego puede hacer un @SuppressWarnings("unchecked") .

También de acuerdo con javadoc deberías ser capaz de hacer esto:

 List stooges = Arrays.asList("Larry", "Moe", "Curly"); 

Pero no puedo hacer que compile con JDK 1.6.

 Collections.singletonList(messageBody) 

¡Si necesitara tener una lista de un artículo !

Colecciones es del paquete java.util .

Aquí está el código de AbacusUtil

 // ArrayList List list = N.asList("Buenos Aires", "cordova", "La Plata"); // HashSet Set set = N.asSet("Buenos Aires", "cordova", "La Plata"); // HashMap Map map = N.asMap("Buenos Aires", 1, "cordova", 2, "La Plata", 3); // Or for Immutable List/Set/Map ImmutableList.of("Buenos Aires", "cordova", "La Plata"); ImmutableSet.of("Buenos Aires", "cordova", "La Plata"); ImmutableSet.of("Buenos Aires", 1, "cordova", 2, "La Plata", 3); // The most efficient way, which is similar with Arrays.asList(...) in JDK. // but returns a flexible-size list backed by the specified array. List set = Array.asList("Buenos Aires", "cordova", "La Plata"); 

Declaración: soy el desarrollador de AbacusUtil.

Para mí, Arrays.asList () es el mejor y más conveniente. Siempre me gusta inicializar de esa manera. Si eres un principiante en Java Collections, me gustaría que refieras la inicialización de ArrayList

La mejor manera de hacerlo:

 package main_package; import java.util.ArrayList; public class Stackkkk { public static void main(String[] args) { ArrayList list = new ArrayList(); add(list, "1", "2", "3", "4", "5", "6"); System.out.println("I added " + list.size() + " element in one line"); } public static void add(ArrayList list,Object...objects){ for(Object object:objects) list.add(object); } } 

Simplemente cree una función que pueda tener tantos elementos como desee y llámelo para agregarlos en una línea.

¿Por qué no hacer una función de utilidad simple que hace esto?

 static  ArrayList ll(A... a) { ArrayList l = new ArrayList(a.length); for (A x : a) l.add(x); return l; } 

ll ” significa “lista literal”.

 ArrayList places = ll("Buenos Aires", "cordova", "La Plata"); 

En realidad, es posible hacerlo en una línea:

 Arrays.asList(new MyClass[] {new MyClass("arg1"), new MyClass("arg2")}) 
 public static  List asList(T... a) { return new ArrayList(a); } 

Esta es la implementación de Arrays.asList , por lo que podría ir con

 ArrayList arr = (ArrayList) Arrays.asList("1", "2");