Pages

Thursday, December 19, 2019

Java Program To Copy(Add) All List Values To A new ArrayList

1. Overview


In this tutorial, We'll be learning how to copy all list values to another new List or ArrayList in Java. Here our context copy means adding all values to a new List. how to copy list values to another list in java or Copy a List to Another List in Java can be done in many ways in java.
And We will keep tracking and show all the possible errors that encounter in our practice programs. Please read the entire article to get a better deeper understanding.

We have already written an article on ArrayList API Methods and its examples.

Java Program To Copy(Add) All List Values To A new ArrayList


We will be showing the example programs using constructor, addAll method, Using Java 8 and Java 10 concepts finally using Collections.copy() method. Hope this article will be interesting for you.

Note: ArrayList is not an Immutable object.


Let us start with the constructor first.

2. Using ArrayList Constructor


ArrayList has an overloaded constructor as below which takes Collection as an argument. So, we pass the original list to the constructor and creates a new list.

ArrayList(Collection<? extends E> c) 

Read the article on How to add values to ArrayList?

Example:

package com.javaprogramto.w3schools.programs.list;

import java.util.ArrayList;
import java.util.List;

public class ArrayListCopyContructor {

    public static void main(String[] args) {

        // Creating arraylist
        List<String> fruits = new ArrayList<>();

        // Adding values
        fruits.add("Orange");
        fruits.add("Apple");
        fruits.add("Grapes");

        System.out.println("Original fruits list values : " + fruits);

        // Copying values to new arraylist
        List<String> fruitsCopy = new ArrayList<>(fruits);
        
        // printing new list values.
        System.out.println("new fruitsCopy list values : "+fruitsCopy);

    }

}

Output:

Original fruits list values : [Orange, Apple, Grapes]
new fruitsCopy list values : [Orange, Apple, Grapes]

If we pass null to the ArrayList constructor then it produces a runtime exception saying "java.lang.NullPointerException".

List<String> fruitsCopy = new ArrayList<>(null);


Exception:


Exception in thread "main" java.lang.NullPointerException
    at java.util.ArrayList.<init>(ArrayList.java:178)
    at com.javaprogramto.w3schools.programs.list.ArrayListCopyContructor.main(ArrayListCopyContructor.java:21)

3. Using addAll() method


ArrayList API has a method addAll() which takes the collection as an argument.

public boolean addAll(Collection<? extends E> c)

Appends all of the elements in the specified collection to the end of this list

Example Code:

package com.javaprogramto.w3schools.programs.list;

import java.util.ArrayList;
import java.util.List;

public class ArrayListCopyAddAll {

    public static void main(String[] args) {

        // Creating arraylist
        List<String> originalFruitsList = new ArrayList<>();

        // Adding values
        originalFruitsList.add("Orange");
        originalFruitsList.add("Apple");
        originalFruitsList.add("Grapes");

        System.out.println("originalFruitsList : " + originalFruitsList);

        // Copying values to new arraylist
        List<String> fruitsCopyList = new ArrayList<>();
        fruitsCopyList.addAll(originalFruitsList);

        // printing new list values.
        System.out.println("New fruitsCopyList : " + fruitsCopyList);

        // Adding few more values to original list.
        originalFruitsList.add("Banana");

        System.out.println("Priting originalFruitsList after appending new values : " + originalFruitsList);
        System.out.println("Priting fruitsCopyList after appending new values : " + fruitsCopyList);
    }
}

Output:


originalFruitsList : [Orange, Apple, Grapes]
New fruitsCopyList : [Orange, Apple, Grapes]
Priting originalFruitsList after appending new values : [Orange, Apple, Grapes, Banana]
Priting fruitsCopyList after appending new values : [Orange, Apple, Grapes]

In the above program, I first created a list originalFruitsList and added three values to it. Next created a new ArrayList fruitsCopyList and invoked addAll(originalFruitsList) with passing originalFruitsList. Now, I printed both lists and have the same values in both lists. So, values are copied from originalFruitsList to fruitsCopyList.


Next, Added new values to the originalFruitsList and printed both list's values again. originalFruitsList only has the new value-added but fruitsCopyList is not having the newly added value. That means modifications to the originalFruitsList do not affect the newly created list from originalFruitsList.

This is the behavior when using the constructor and allAll() method.

4. Using Collections.copy() method


Collections.copy() method takes two List arguments such as dest and src. It copies values from the src list to the dest list. The order is the same as in the src list.
Copies all of the elements from one list into another.


public static <T> void copy(List<? super T> dest, List<? extends T> src)

package com.javaprogramto.w3schools.programs.list;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class ArrayListCopyCollectionsCopy {

    public static void main(String[] args) {

        // Creating arraylist
        List<String> originalFruitsList = new ArrayList<>();

        // Adding values
        originalFruitsList.add("Orange");
        originalFruitsList.add("Apple");
        originalFruitsList.add("Grapes");

        System.out.println("originalFruitsList : " + originalFruitsList);

        // Copying values to new arraylist
        List<String> fruitsCopyList = new ArrayList<>();

        Collections.copy(fruitsCopyList, originalFruitsList);

        System.out.println("fruitsCopyList : " + fruitsCopyList);

    }
}

The above program gives the below runtime problem.

If the src and dest list size are diffrerent then it will throw IndexOutOfBoundsException.


java.lang.IndexOutOfBoundsException: Source does not fit in dest
    at java.util.Collections.copy(Collections.java:558)
    at com.javaprogramto.w3schools.programs.list.ArrayListCopyCollectionsCopy.main(ArrayListCopyCollectionsCopy.java:28)

src list size is 3 and the dest list size is 0. When using copy() method dest list size must be equal or greater than the src list.

If you try to set the ArrayList size to 3 using constructor will give the same IndexOutOfBoundsException.

List<String> fruitsCopyList = new ArrayList<>(3);

Because above line initializes the size of the ArrayList with three. That means a maximum of 3 elements values can be added but when it reaches threshold then it will be resized.

To make working our example, we must need to add a few dummy values to the destination list as below.

fruitsCopyList.add("1");
fruitsCopyList.add("2");
fruitsCopyList.add("3");

Now, this program runs successfully and produces the below output.

originalFruitsList : [Orange, Apple, Grapes]
fruitsCopyList : [Orange, Apple, Grapes]

Note: If the destination size is more than the src list then the reaming elements in the dest list will remain unchanged.

5. Using Java 8 Streams


Java 8 Introduced Streams and Lambda Expressions to reduce the code to be written and increases focus on business logic rather than syntax. Java 8 following functional programming similar to Scala.


Let us take a look at copying all values of the list to another list using java 8 streams api.

This example program covers the following.

A) Adding all values to a new list.
B) Skipping the first record and add reaming to the new list.
C) Find and add the fruit name length that equal to 5 to the new list.


package com.javaprogramto.w3schools.programs.list;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

public class ArrayListCopyCollectionsCopy {

    public static void main(String[] args) {

        // Creating arraylist
        List<String> originalFruitsList = new ArrayList<>();

        // Adding values
        originalFruitsList.add("Orange");
        originalFruitsList.add("Apple");
        originalFruitsList.add("Grapes");

        System.out.println("originalFruitsList : " + originalFruitsList);

        // copying all values to a new list.
        List<String> fruitesCopyList = originalFruitsList.stream().collect(Collectors.toList());
        System.out.println("All values into fruitesCopyList : " + fruitesCopyList);

        // skipping the first value.
        List<String> skippingFirstValue = originalFruitsList.stream().skip(1).collect(Collectors.toList());
        System.out.println("Skipping first value : " + skippingFirstValue);

        // fruit name length == 5
        List<String> fruitLength5 = originalFruitsList.stream().filter(fruit -> fruit.length() == 5)
                .collect(Collectors.toList());
        System.err.println("Fruites length == 5 :  fruitLength5 " + fruitLength5);

    }
}

Output:


originalFruitsList : [Orange, Apple, Grapes]
All values into fruitesCopyList : [Orange, Apple, Grapes]
Skipping first value : [Apple, Grapes]
Fruites length == 5 :  fruitLength5 [Apple]


6. Using Java 10 new method


JDK 10 released with the new method copyOf​() in List interface.

Syntax:

static <E> List<E> copyOf​(Collection<? extends E> coll)

Returns an unmodifiable List containing the elements of the given Collection, in its iteration order. The given Collection must not be null, and it must not contain any null elements. If the given Collection is subsequently modified, the returned List will not reflect such modifications.


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

If the list is empty or the list has null values then it will throw NullPointerException.


7. List ConcurrentAccessException


A common problem when working with lists is 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 do 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



To avoid the concurrent access problems, you should use CopyOnWriteArrayList implementation which the copy of the original list when a thread is changing the values it creates a new copy for each mutative operation.

8. Conclusion


In this article, we have seen all the strategies to copy a list to another. These strategies include the addAll(), constructor, copy(), java 8 streams and java 10 new method.

And also what is the right way to work with ArrayList in concurrent environments.

No comments:

Post a Comment

Please do not add any spam links in the comments section.