Copiar uma lista para outra lista em Java

Copiar uma lista para outra lista em Java

1. Visão geral

Neste tutorial rápido, mostraremos diferentes maneiras de copiar umList para outroListe um erro comum produzido no processo.

Para obter uma introdução ao uso deCollections, consulteto this article here.

2. Construtor

Uma maneira simples de copiar umList é usando o construtor que recebe uma coleção como argumento:

List copy = new ArrayList<>(list);

Devido ao fato de que estamos copiando a referência aqui e não clonando os objetos, todas as alterações feitas em um elemento afetarão as duas listas.

Por esse motivo, é bom usar o construtor para copiar objetos imutáveis:

List copy = new ArrayList<>(list);

Integer é uma classe imutável, seu valor é definido quando a instância é criada e nunca pode ser alterado.

Uma referênciaInteger pode, portanto, ser compartilhada por várias listas e tópicos e não há como alguém alterar seu valor.

3. ListConcurrentAccessException

A common problem working with lists is the ConcurrentAccessException. Isso pode significar que estamos modificando a lista enquanto tentamos copiá-la, provavelmente em outro tópico.

Para corrigir esse problema, precisamos:

  • Use um projetado para coleta de acesso simultâneo

  • Bloqueie a coleção adequadamente para iterá-la

  • Encontre uma maneira de evitar a necessidade de copiar a coleção original

Considerando nossa última abordagem, não é thread-safe. Portanto, se quisermos resolver nosso problema com a primeira opção, podemos usarCopyOnWhiteArrayList, em que todas as operações mutativas são implementadas fazendo uma nova cópia do array subjacente.

Para obter mais informações, consulteto this article.

Caso desejemos bloquear oCollection, é possível usar uma primitiva de bloqueio para serializar o acesso de leitura / gravação, comoReentrantReadWriteLock.

4. AddAll

Outra abordagem para copiar elementos é usar o métodoaddAll:

List copy = new ArrayList<>();
copy.addAll(list);

É importante ter em mente, sempre que usar esse método, que, como acontece com o construtor, o conteúdo de ambas as listas fará referência aos mesmos objetos

5. Collections.copy

A classeCollections consiste exclusivamente em métodos estáticos que operam ou retornam coleções.

Um deles écopy, que precisa de uma lista de origem e uma lista de destino pelo menos tão longa quanto a origem.

Ele manterá o índice de cada elemento copiado na lista de destinos, como o original:

List source = Arrays.asList(1,2,3);
List dest = Arrays.asList(4,5,6);
Collections.copy(dest, source);

No exemplo acima, todos os elementos anteriores na listadest foram substituídos porque ambas as listas têm o mesmo tamanho.

Caso o tamanho da lista de destinos seja maior que a origem:

List source = Arrays.asList(1, 2, 3);
List dest = Arrays.asList(5, 6, 7, 8, 9, 10);
Collections.copy(dest, source);

Apenas os três primeiros itens foram substituídos enquanto o restante dos elementos da lista são conservados.

6. Usando Java 8

Esta versão do Java abre nossas possibilidades adicionando novas ferramentas. O que exploraremos nos próximos exemplos éStream:

List copy = list.stream()
  .collect(Collectors.toList());

As principais vantagens dessa maneira são a oportunidade de usar filtros e pular. No próximo exemplo, vamos pular o primeiro elemento:

List copy = list.stream()
  .skip(1)
  .collect(Collectors.toList());

É possível filtrar pelo comprimento deString também ou comparando um atributo de nossos objetos:

List copy = list.stream()
  .filter(s -> s.length() > 10)
  .collect(Collectors.toList());
List flowers = list.stream()
  .filter(f -> f.getPetals() > 6)
  .collect(Collectors.toList());

É provável que queiramos trabalhar de maneira nula segura:

List flowers = Optional.ofNullable(list)
  .map(List::stream)
  .orElseGet(Stream::empty)
  .collect(Collectors.toList());

E pule um elemento usando desta maneira também:

List flowers = Optional.ofNullable(list)
  .map(List::stream).orElseGet(Stream::empty)
  .skip(1)
  .collect(Collectors.toList());

7. Usando Java 10

Finalmente, uma das últimas versões do Java nos permite criar umList imutável contendo os elementos doCollection: fornecido

List copy = List.copyOf(list);

As únicas condições são que a coleção fornecida não deve ser nula e não deve conter nenhum elemento nulo.

8. Conclusão

Neste artigo, exploramos maneiras diferentes de copiar umList para outroList com versões deJava diferentes e um erro comum produzido no processo.

Como sempre, os exemplos de código podem ser encontrados no GitHubhereehere.