Copy a List to Another List in Java

1. Overview

In this quick tutorial, we’ll show different ways to copy a List to another List and a common error produced in the process.

For an introduction to the use of Collections, please refer to this article here.

2. Constructor

A simple way to copy a List is by using the constructor that takes a collection as its argument:

List<Plant> copy = new ArrayList<>(list);

Due to the fact that we’re copying reference here and not cloning the objects,  every amends made in one element will affect both lists.

For that reason, using the constructor is good to copy immutable objects:

List<Integer> copy = new ArrayList<>(list);

Integer is an immutable class, its value is set when the instance is created and can never change.

An Integer reference can thus be shared by multiple lists and threads and there’s no way anybody can change its value.

3. List ConcurrentAccessException

A common problem working with lists is the ConcurrentAccessException. This could mean that we’re modifying the list while we’re trying to copy it, most likely in another thread.

To fix this issue we have to either:

  • Use a designed for concurrent access collection
  • Lock the collection appropriately to iterate over it
  • Find a way to avoid needing to copy the original collection

Considering our last approach, it isn’t thread-safe. So that if we want to resolve our problem with the first option, we may want to use CopyOnWriteArrayList, in which all mutative operations are implemented by making a fresh copy of the underlying array.

In case we want to lock the Collection, it’s possible to use a lock primitive to serialize read/write access, such as ReentrantReadWriteLock.

4. AddAll

Another approach to copy elements is using the addAll method:

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

It’s important to keep on mind whenever using this method that, as with the constructor, the contents of both lists will reference the same objects.

5. Collections.copy

The Collections class consists exclusively of static methods that operate on or return collections.

One of them is copy, which needs a source list and a destination list at least as long as the source.

It will maintain the index of each copied element in the destination list such as the original:

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

In the above example, all the previous elements in the dest list were overwritten because both lists have the same size.

In case that the destination list size is larger than the source:

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

Just the three first items were overwritten while the rest of the elements in the list are conserved.

6. Using Java 8

This version of Java opens our possibilities by adding new tools. The one we will explore in the next examples is Stream:

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

The main advantages of this way are the opportunity to use skip and filters. In the next example we’re going to skip the first element:

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

It’s possible to filter by the length of the String too or by comparing an attribute of our objects:

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

It’s probable we want to work in a null-safe way:

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

And skip an element using this way too:

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

7. Using Java 10

Finally, one of the last Java version allows us to create an immutable List containing the elements of the given Collection:

List<T> copy = List.copyOf(list);

The only conditions are that the given Collection mustn’t be null, and it mustn’t contain any null elements.

8. Conclusion

In this article, we’ve explored different ways to copy a List to another List with different Java versions and a common error produced in the process.As always, code samples can be found over on GitHub.

Related posts:

Introduction to Spring Cloud Rest Client with Netflix Ribbon
Java Program to Perform Postorder Non-Recursive Traversal of a Given Binary Tree
Base64 encoding và decoding trong Java 8
Spring Boot - Building RESTful Web Services
Guide to Java Instrumentation
Java Program to Find Nearest Neighbor Using Linear Search
Java Program to Find the Connected Components of an UnDirected Graph
Batch Processing with Spring Cloud Data Flow
Test a REST API with Java
HTTP Authentification and CGI/Servlet
Java Program to Solve a Matching Problem for a Given Specific Case
Java Program to Check Whether a Weak Link i.e. Articulation Vertex Exists in a Graph
Comparing Dates in Java
Java Program to Implement Fibonacci Heap
Java Program to Generate Random Numbers Using Multiply with Carry Method
Get the workstation name or IP
ETL with Spring Cloud Data Flow
Calling Stored Procedures from Spring Data JPA Repositories
Java InputStream to Byte Array and ByteBuffer
Tạo ứng dụng Java RESTful Client với thư viện OkHttp
Java Program to Implement ConcurrentSkipListMap API
Get and Post Lists of Objects with RestTemplate
Recommended Package Structure of a Spring Boot Project
A Guide to the ResourceBundle
Hướng dẫn Java Design Pattern – DAO
Java Program to Implement LinkedHashMap API
Java Program to Print the Kind of Rotation the AVL Tree is Undergoing
Java Program to Check Cycle in a Graph using Topological Sort
Creating a Web Application with Spring 5
Servlet 3 Async Support with Spring MVC and Spring Security
Getting Started with Stream Processing with Spring Cloud Data Flow
Java Program to Implement Sieve Of Atkin