JavaRush /Blogue Java /Random-PT /As 10 principais perguntas sobre coleções em Java
FedoraLinux
Nível 21
Москва

As 10 principais perguntas sobre coleções em Java

Publicado no grupo Random-PT
O artigo é uma tradução do artigo " As 10 principais perguntas sobre coleções Java " . Abaixo estão as perguntas mais populares sobre coleções em Java, feitas e discutidas no Stackowerflow. Antes de analisar essas questões, seria bom examinar o diagrama de hierarquia de classes. 1. Quando usar LinkedList em vez de ArrayList? Um ArrayList é na verdade um array; seus elementos podem ser acessados ​​diretamente pelo índice. Se o array transbordar, será necessário um novo com mais espaço. Colocar e mover todos os elementos levará tempo O(n). Além disso, adicionar e remover elementos é necessário para mover os elementos existentes na matriz. Este é talvez o maior inconveniente de usar ArrayList. LinkedList é uma lista dupla de links de elementos. Assim, para acessar o elemento do centro, é necessário pesquisar do início ao fim da planilha. Por outro lado, adicionar e remover um elemento em uma LinkedList é mais rápido porque essas operações alteram apenas a própria lista. Os piores momentos são comparados abaixo:
Método Lista de matrizes Lista vinculada
obter (índice) O(1) Sobre)
adicionar (E) Sobre) O(1)
adicionar(E, índice) Sobre) Sobre)
remover (índice) Sobre) Sobre)
Iterador.remove() Sobre) O(1)
Iterador.add(E) Sobre) O(1)
Apesar do tempo de execução, o uso de memória deve ser considerado individualmente para listas grandes. Em uma LinkedList, cada nó deve ter pelo menos dois ponteiros adicionais para vincular os nós anterior e seguinte, enquanto em uma ArrayList, apenas uma matriz de elementos é necessária. Mais comparações de listas ArrayList, LinkedList e Vector . 2. Equivalente eficiente para remover elementos durante a iteração da coleção A única maneira correta de modificar (remover elementos) uma coleção durante a iteração é usar Iterator.remove() . Por exemplo: O erro mais comum é: Você receberá uma ConcurrentModificationException ao executar o código acima. Isso acontece porque o iterador foi gerado para percorrer toda a lista, mas ao mesmo tempo a planilha é alterada chamando Iterator.remove(). Conforme escrito na documentação para esta exceção, Iterator itr = list.iterator(); while(itr.hasNext()) { // do something itr.remove(); } for(Integer i: list) { list.remove(i); }
"geralmente não é permitido que um thread modifique uma coleção enquanto outro thread está iterando sobre ela."
Em geral, é inaceitável que um thread modifique uma coleção enquanto outro thread a atravessa. 3. Como converter Lista em array int[]? A maneira mais fácil de fazer isso é usar ArrayUtils , localizado na biblioteca Apache Commons Lang . int[] array = ArrayUtils.toPrimitive(list.toArray(new Integer[0])); Não há atalho para esta expressão no JDK. Lembre-se de que você não pode usar List.toArray() porque esta expressão converte List em Integer[] (que não é um tipo primitivo). A forma correta seria a seguinte opção: int[] array = new int[list.size()]; for(int i=0; i < list.size(); i++) { array[i] = list.get(i); } 4. Como converter um array int[] em uma Lista? A maneira mais fácil também é usar ArrayUtils na biblioteca Apache Commons Lang , como acima. List list = Arrays.asList(ArrayUtils.toObject(array)); Além disso, não há atalho para esta expressão no JDK. 5. Qual a melhor forma de filtrar a coleção? Você pode usar pacotes de terceiros, como Guava ou Apache Commons Lang, para aumentar a funcionalidade. Ambos os pacotes possuem um método filter() (na classe Collections2 do Guava e CollectionUtils do Apache). O método filter() retornará elementos que correspondem ao predicado fornecido. No JDK tudo é mais complicado. A boa notícia é que os predicados serão adicionados no Java 8 , mas por enquanto você precisa usar o Iterator para iterar por toda a coleção. Claro, você pode imitar o caminho seguido pelo Guava e pelo Apache familiarizando-se com a nova interface do Predicate. Agora podemos usar o seguinte código para filtrar a coleção: 6. Como converter facilmente List em Set? Existem duas maneiras de fazer isso, dependendo de como você deseja definir igualdade. O primeiro trecho de código coloca a lista em um HashSet. A duplicata neste caso é determinada principalmente por hashCode(). Normalmente isso funcionará. Mas se você precisar levar em conta o caminho de comparação, então seria melhor usar a segunda parte do código, onde você pode definir seu próprio comparador. 7. Como posso remover elementos duplicados de um ArrayList? Esta questão está um pouco relacionada com a questão acima. Se a ordem dos elementos no ArrayList não importa para você, uma jogada inteligente seria colocar a planilha em um Conjunto para remover duplicatas e, em seguida, devolvê-la à Lista. Abaixo está um exemplo. Se a ordem dos elementos for importante para você, então a ordem pode ser garantida colocando a lista em um LinkedHashSet , que está no JDK padrão. 8. Coleção ordenada int[] array = {1,2,3,4,5}; List list = new ArrayList (); for(int i: array) { list.add(i); } Iterator itr = list.iterator(); while(itr.hasNext()) { int i = itr.next(); if (i > 5) { // filter all ints bigger than 5 itr.remove(); } } public interface Predicate { boolean test(T o); } public static void filter(Collection collection, Predicate predicate) { if ((collection != null) && (predicate != null)) { Iterator itr = collection.iterator(); while(itr.hasNext()) { T obj = itr.next(); if (!predicate.test(obj)) { itr.remove(); } } } } filter(list, new Predicate () { public boolean test(Integer i) { return i <= 5; } }); Set set = new HashSet (list); Set set = new TreeSet (aComparator); set.addAll(list); ArrayList** list = ... // initial a list with duplicate elements Set set = new HashSet (list); list.clear(); list.addAll(set); Existem várias maneiras de oferecer suporte a uma coleção classificada em Java. Todos eles fornecem uma coleção em ordem natural ou por um comparador especificado. No caso de ordem natural, você também precisa implementar a interface Comparable no elemento.
  1. Collections.sort() pode classificar uma lista. Conforme declarado na documentação Java, essa classificação é estável e garante desempenho n log(n).
  2. PriorityQueue fornece uma fila ordenada. A diferença entre PriorityQueue e Collections.sort() é que PriorityQueue mantém a ordem da fila o tempo todo, mas você só pode obter o primeiro elemento da fila. Você não pode acessar aleatoriamente um elemento como PriorityQueue.get(4).
  3. Se não houver duplicatas na coleção, você poderá selecionar TreeSet . Também como PriorityQueue, TreeSet mantém um conjunto ordenado o tempo todo. Você pode obter o menor ou maior elemento de um TreeSet, mas ainda não pode ter acesso aleatório aos elementos.
Simplificando, Collections.sort() fornece uma lista ordenada única. PriorityQueue e TreeSet mantêm uma coleção ordenada o tempo todo, ao custo da falta de acesso indexado aos elementos. 9. Collections.emptyList() ou nova instância A mesma questão se aplica a emptyMap() e emptySet(). Ambos os métodos retornam uma lista vazia, mas Collections.emptyList() é uma lista imutável. Isso significa que você não pode adicionar novos elementos a uma lista “vazia”. Em segundo plano, cada chamada ao método Collections.emptyList() não cria realmente uma nova instância da lista vazia. Em vez disso, reutilizará a instância vazia já existente. Se você está familiarizado com Singleton como padrão de design , deve entender o que isso significa. Isso deve proporcionar melhor desempenho se for chamado com frequência. 10 Copiando uma coleção, Collections.copy() Existem duas maneiras de copiar uma lista de origem para uma lista de destino. Uma maneira é usar o construtor ArrayList. Outra maneira é usar o método Collections.copy() . Observe a primeira linha: estamos alocando uma lista que é pelo menos tão longa quanto o comprimento da lista original, porque a documentação Java sobre coleções diz: ArrayList dstList = new ArrayList (srcList);
A lista de destinos deve ser pelo menos tão longa quanto a lista de origem.
O que significa que a lista final não deve ser menor que a original. Ambos os métodos são cópias superficiais. Então, qual é a diferença entre esses dois métodos? Primeiro, Collections.copy() não realocará a capacidade da coleção dstList, mesmo que dstList não tenha espaço suficiente para conter todos os elementos de srcList. Em vez disso, lançará IndexOutOfBoundsException . Alguém poderia perguntar se há algum benefício nisso. A razão é que isso garante que o método seja executado linearmente no tempo. Isso também é adequado quando você deseja reutilizar matrizes em vez de realocar memória no construtor ArrayList. Em vez de uma conclusão Se depois de ler o artigo você ainda tiver dúvidas, fique à vontade para perguntar nos comentários. Além disso, se você encontrar alguma imprecisão na tradução ou qualquer outro erro, escreva para o PM, ele será corrigido e você será agradecido. Original. ArrayList dstList = new ArrayList (srcList.size()); Collections.copy(dstList, srcList);
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION