Creating a List from an Array


The Arrays.asList() method can be used to return a fixed-size List containing the elements of the given array. The resulting List will be of the same parameter type as the base type of the array.

String[] stringArray = {"pink", "white", "red"};
List<String> stringList = Arrays.asList(stringArray);

Note : This list is backed by (a view of) the original array, meaning that any changes to the list will change the array and vice versa. However, changes to the list that would change its size (and hence the array length) will throw an exception.

To create a copy of the list, use the constructor of java.util.ArrayList taking a Collection as an argument

String[] stringArray = {"Pink", "White", "Red"};
List<String> stringList = new ArrayList<String>(Arrays.asList(stringArray));

In Java SE 7 and later, a pair of angle brackets <> (empty set of type arguments) can be used, which is called the Diamond. The compiler can determine the type arguments from the context. This means the type information can be left out when calling the constructor of ArrayList and it will be inferred automatically during compilation. This is called Type Inference which is a part of Java Generics.

String[] words = {"apple", "banana", "orange"};
List<String> wordList = new ArrayList<>(Arrays.asList(words));
 
String[] items = {"pen", "paper", "book"};
ArrayList<String> itemList = new ArrayList<>();
itemList.addAll(Arrays.asList(items));
 
String[] texts = {"hello", "world", "Java"};
ArrayList<String> textList = new ArrayList<>();
Collections.addAll(textList, texts);

A point worth noting about the Diamond is that it cannot be used with Anonymous Classes.

// Using Streams
int[] ints = {1, 2, 3};
List<Integer> list = Arrays.stream(ints).boxed().collect(Collectors.toList());
 
String[] stringArray = {"Red", "White", "Pink"};
List<Object> list = Arrays.stream(stringArray).collect(Collectors.toList());

Important notes related to using Arrays.asList() method

  • This method returns List, which is an instance of Arrays$ArrayList(static inner class of Arrays) and not java.util.ArrayList. The resulting List is of fixed-size. That means, adding or removing elements is not supported and will throw an UnsupportedOperationException:
  • stringList.add("something"); // throws java.lang.UnsupportedOperationException
  • A new List can be created by passing an array-backed List to the constructor of a new List. This creates a new copy of the data, which has changeable size and that is not backed by the original array:
  • List<String> modifiableList = new ArrayList<>(Arrays.asList("Pink", "White"));
  • Calling <T> List<T> asList(T... a) on a primitive array, such as an int[], will produce a List<int[]> whose only element is the source primitive array instead of the actual elements of the source array.

The reason for this behavior is that primitive types cannot be used in place of generic type parameters, so the entire primitive array replaces the generic type parameter in this case. In order to convert a primitive array to a List, first of all, convert the primitive array to an array of the corresponding wrapper type (i.e. call Arrays.asList on an Integer[] instead of an int[]).

Therefore, this will print false:

int[] arr = {1, 2, 3}; // primitive array of int
System.out.println(Arrays.asList(arr).contains(1));

On the other hand, this will print true:

Integer[] arr = {1, 2, 3}; // object array of Integer (wrapper for int)
System.out.println(Arrays.asList(arr).contains(1));

This will also print true, because the array will be interpreted as an Integer[]):

System.out.println(Arrays.asList(1,2,3).contains(1));

Creating an Array from a Collection

Two methods in java.util.Collection create an array from a collection:

  • Object[] toArray()
  • <T> T[] toArray(T[] a)

Object[] toArray() can be used as follows:

Set<String> colors = new HashSet<String>();
colors.add("green");
colors.add("yellow");
 
Object[] objectArray = colors.toArray();
 
Set<String> items = new HashSet<String>();
items.add("pen");
items.add("pencil");
 
String[] itemArray = items.toArray(new String[0]);
 
Set<String> fruits = new HashSet<String>();
fruits.add("apple");
fruits.add("orange");
 
String[] fruitArray = fruits.toArray(new String[fruits.size()]);

The difference between them is more than just having untyped vs typed results. Their performance can differ as well (for details please read this performance analysis section):

  • Object[] toArray() uses vectorized arraycopy, which is much faster than the type-checked arraycopy used in T[] toArray(T[] a).
  • T[] toArray(new T[non-zero-size]) needs to zero-out the array at runtime, while T[] toArray(new T[0]) does not. Such avoidance makes the latter call faster than the former. Detailed analysis here : Arrays of Wisdom of the Ancients

Starting from Java SE 8+, where the concept of Stream has been introduced, it is possible to use the Stream produced by the collection in order to create a new Array using the Stream.toArray method.

String[] strings = list.stream().toArray(String[]::new);

Basic Programs