A Interface List
Objective
Entender List: a subinterface de Collection que armazena uma sequência de elementos acessados por um índice baseado em zero, e pode conter duplicatas. Além de tudo que Collection já declara, List adiciona operações posicionais — inserir, ler, substituir, buscar e fatiar por índice.
Use Cases
- Armazenar elementos em uma ordem específica, controlada pelo chamador, em vez do conjunto desordenado que uma
Collectionpura sugere. - Inserir ou substituir um elemento em uma posição conhecida em vez de remover e readicionar.
- Encontrar onde um valor está na sequência com
indexOf/lastIndexOf. - Trabalhar em uma janela de uma lista maior via
subList, sem copiar os dados subjacentes. - Ordenar uma lista in-place, ou aplicar uma transformação a cada elemento com
replaceAll. - Construir rapidamente uma lista pequena, fixa e não modificável com
List.of()em vez denew ArrayList<>(...).
Deep Dive
List estende Collection
javainterface List<E>E especifica o tipo de objetos que a lista vai conter. Como List estende Collection, tudo que Collection declara — add, remove, contains, stream, ... — está disponível, mas List dá a add(E) e addAll(Collection) uma semântica mais específica: os elementos sempre entram em uma posição definida (o final, a menos que indicado de outra forma), e duplicatas são permitidas.
Inserindo em uma posição: add(int, E) e addAll(int, Collection)
javaList<String> names = new ArrayList<>(List.of("Ann", "Cid"));
names.add(1, "Bob"); // insert at index 1
names.addAll(1, List.of("Xx", "Yy")); // insert every element starting at index 1Ambos deslocam todo elemento subsequente para cima pelo número de elementos inseridos, em vez de sobrescrever o que estava lá.
Acesso posicional: get e set
javaString first = names.get(0); // read the element at index 0
names.set(0, "Zoe"); // replace it, returning the old valueset substitui in-place; não muda o tamanho da lista como add faz.
Busca: indexOf e lastIndexOf
javanames.indexOf("Bob"); // first index where Bob appears, or -1
names.lastIndexOf("Bob"); // last index where Bob appears, or -1Ambos comparam com equals(), então encontram qualquer elemento igual ao argumento, não apenas a exata mesma referência.
Sublistas: uma view, não uma cópia
javaList<String> view = names.subList(1, 3); // elements at index 1 and 2subList retorna uma List apoiada na original — leituras e escritas em view são repassadas para names naquela faixa de índices.
Substituindo e ordenando in-place
javanames.replaceAll(String::toUpperCase); // apply a function to every element
names.sort(Comparator.naturalOrder()); // sort using a Comparatorsort() é declarado pela própria List (não herdado de Collection), então qualquer implementação de List ganha ordenação in-place sem uma chamada separada a algum utilitário.
Listas não modificáveis: List.of()
A partir do JDK 9, List inclui o método de fábrica of(), com 12 sobrecargas (de zero a dez argumentos, mais uma forma varargs):
javaList<String> empty = List.of();
List<String> one = List.of("Ann");
List<String> many = List.of("Ann", "Bob", "Cid", "Dee", "Eve", "Fay", "Gio", "Hal", "Ida", "Jax");
List<String> varargs = List.of("k1", "k2", "k3", "k4", "k5", "k6", "k7", "k8", "k9", "k10", "k11");Toda versão retorna uma lista não modificável, baseada em valor. Elementos null não são permitidos em nenhuma delas.
Trade-offs
Listas não modificáveis rejeitam mutação em tempo de execução, não em tempo de compilação — uma lista vinda de
List.of()ainda expõeadd/set/remove, então chamar um desses passa na checagem de tipos normalmente e só falha quando executado:javaList<String> fixed = List.of("a", "b"); fixed.add("c"); // UnsupportedOperationExceptionMétodos posicionais validam o índice contra o tamanho atual —
get,seteadd(int, E)lançamIndexOutOfBoundsExceptionpara um índice negativo ou fora do intervalo, em vez de simplesmente limitá-lo silenciosamente:javaList<String> names = new ArrayList<>(List.of("Ann")); names.get(5); // IndexOutOfBoundsExceptionsubList é uma view ao vivo, então mudanças estruturais em qualquer um dos lados ficam visíveis nos dois — mutar através da view muta a lista de suporte in-place:
javaList<String> names = new ArrayList<>(List.of("Ann", "Bob", "Cid")); List<String> view = names.subList(0, 2); view.set(0, "Zoe"); System.out.println(names); // [Zoe, Bob, Cid]sort() só precisa de elementos que sejam de fato mutuamente comparáveis, e isso não é checado até a execução —
List<E>não exige queEimplementeComparablea menos que o chamador use a ordem natural, então uma lista de objetos genuinamente incomparáveis compila normalmente e só falha quandosort()tenta comparar dois deles.