A resposta simples
No Java 9 ou posterior, depois List.of()
foi adicionado:
List<String> strings = List.of("foo", "bar", "baz");
Com o Java 10 ou posterior, isso pode ser reduzido com a var
palavra - chave.
var strings = List.of("foo", "bar", "baz");
Isso lhe dará um imutável List
, por isso não pode ser alterado.
Qual é o que você deseja na maioria dos casos em que está pré-preenchendo-o.
Java 8 ou anterior:
List<String> strings = Arrays.asList("foo", "bar", "baz");
Isso lhe dará um List
respaldo por uma matriz, portanto, não pode alterar o comprimento.
Mas você pode ligar List.set
, por isso ainda é mutável .
Você pode Arrays.asList
diminuir ainda mais com uma importação estática:
List<String> strings = asList("foo", "bar", "baz");
A importação estática:
import static java.util.Arrays.asList;
O que qualquer IDE moderno sugerirá e fará automaticamente por você.
Por exemplo, no IntelliJ IDEA, você pressiona Alt+Enter
e seleciona Static import method...
.
No entanto, eu não recomendo encurtar o List.of
método para of
, porque isso se torna confuso.
List.of
já é curto o suficiente e lê bem.
Usando Stream
s
Por que tem que ser um List
?
Com o Java 8 ou posterior, você pode usar um Stream
que seja mais flexível:
Stream<String> strings = Stream.of("foo", "bar", "baz");
Você pode concatenar Stream
s:
Stream<String> strings = Stream.concat(Stream.of("foo", "bar"),
Stream.of("baz", "qux"));
Ou você pode ir de a Stream
para List
:
import static java.util.stream.Collectors.toList;
List<String> strings = Stream.of("foo", "bar", "baz").collect(toList());
Mas de preferência, basta usar o Stream
sem coletá-lo para a List
.
Se você realmente precisa especificamente de umjava.util.ArrayList
(Você provavelmente não.)
Para citar JEP 269 (ênfase minha):
Há um pequeno conjunto de casos de uso para inicializar uma instância de coleção mutável com um conjunto predefinido de valores. Geralmente, é preferível ter esses valores predefinidos em uma coleção imutável e, em seguida, inicializar a coleção mutável por meio de um construtor de cópia.
Se você quer tanto um pré-popular ArrayList
e adicionar a ele posteriormente (por quê?), Uso
ArrayList<String> strings = new ArrayList<>(List.of("foo", "bar"));
strings.add("baz");
ou no Java 8 ou anterior:
ArrayList<String> strings = new ArrayList<>(asList("foo", "bar"));
strings.add("baz");
ou usando Stream
:
import static java.util.stream.Collectors.toCollection;
ArrayList<String> strings = Stream.of("foo", "bar")
.collect(toCollection(ArrayList::new));
strings.add("baz");
Mas, novamente, é melhor usar o Stream
diretamente em vez de coletá-lo para a List
.
Programa para interfaces, não para implementações
Você disse que declarou a lista como ArrayList
no seu código, mas você só deve fazer isso se estiver usando algum membro do ArrayList
qual não esteja List
.
O que você provavelmente não está fazendo.
Normalmente, você deve apenas declarar variáveis pela interface mais geral que você está indo para uso (por exemplo Iterable
, Collection
ou List
), e inicialize-los com a aplicação específica (por exemplo ArrayList
, LinkedList
ou Arrays.asList()
).
Caso contrário, você está limitando seu código a esse tipo específico, e será mais difícil mudar quando você desejar.
Por exemplo, se você está passando um ArrayList
para um 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
}
Outro exemplo seria sempre declarar a variável an InputStream
mesmo que seja geralmente uma FileInputStream
ou a BufferedInputStream
, porque um dia em breve você ou outra pessoa desejará usar algum outro tipo de InputStream
.
ArrasyList<String> places = ["Buenos Aires", "Córdoba", "La Plata"]