La respuesta simple
En Java 9 o posterior, después List.of()se agregó:
List<String> strings = List.of("foo", "bar", "baz");
Con Java 10 o posterior, esto se puede acortar con la varpalabra clave.
var strings = List.of("foo", "bar", "baz");
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:
List<String> strings = Arrays.asList("foo", "bar", "baz");
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:
List<String> strings = asList("foo", "bar", "baz");
La importación estática:
import static java.util.Arrays.asList;
Lo que cualquier IDE moderno sugerirá y hará automáticamente por usted.
Por ejemplo, en IntelliJ IDEA, presiona Alt+Entery selecciona Static import method....
Sin embargo, no recomiendo acortar el List.ofmétodo of, 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:
Stream<String> strings = Stream.of("foo", "bar", "baz");
Puedes concatenar Streams:
Stream<String> strings = Stream.concat(Stream.of("foo", "bar"),
Stream.of("baz", "qux"));
O puedes ir de un Streama un List:
import static java.util.stream.Collectors.toList;
List<String> strings = Stream.of("foo", "bar", "baz").collect(toList());
Pero preferiblemente, solo use el Streamsin recogerlo a List.
Si realmente necesitas unjava.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 tanto una rellenar previamente ArrayList y agregar a ella después (¿por qué?), El uso
ArrayList<String> strings = new ArrayList<>(List.of("foo", "bar"));
strings.add("baz");
o en Java 8 o anterior:
ArrayList<String> strings = new ArrayList<>(asList("foo", "bar"));
strings.add("baz");
o usando Stream:
import static java.util.stream.Collectors.toCollection;
ArrayList<String> strings = Stream.of("foo", "bar")
.collect(toCollection(ArrayList::new));
strings.add("baz");
Pero, de nuevo, es mejor usar Streamdirectamente en lugar de recopilarlo en a List.
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 miembro ArrayListque no está en List.
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, Collectiono List), e inicializar con la aplicación específica (por ejemplo ArrayList, LinkedListo Arrays.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 un void method(...):
// Iterable if you just need iteration, for (String s : strings):
void method(Iterable<String> strings) {
for (String s : strings) { ... }
}
// Collection if you also need .size(), .isEmpty(), or .stream():
void method(Collection<String> strings) {
if (!strings.isEmpty()) { strings.stream()... }
}
// List if you also need .get(index):
void method(List<String> strings) {
strings.get(...)
}
// Don't declare a specific list implementation
// unless you're sure you need it:
void method(ArrayList<String> strings) {
??? // You don't want to limit yourself to just ArrayList
}
Otro ejemplo sería siempre declarar una variable InputStreama pesar de que generalmente es a FileInputStreamo a BufferedInputStream, porque un día pronto usted u otra persona querrán usar otro tipo de InputStream.
ArrasyList<String> places = ["Buenos Aires", "Córdoba", "La Plata"]