Arrays.asList() vs Collections.singletonList()

JavaCollections

Java Problem Overview


Is there an advantage (or much of a difference) to using Arrays.asList(something) over Collections.singletonList(something) to make a list containing one item? The latter makes the returned list immutable as well.

Java Solutions


Solution 1 - Java

Collections.singletonList(something) is immutable whereas Arrays.asList(something) is a fixed size List representation of an Array where the List and Array gets joined in the heap.

Arrays.asList(something) allows non-structural changes made to it, which gets reflected to both the List and the conjoined array. It throws UnsupportedOperationException for adding, removing elements although you can set an element for a particular index.

Any changes made to the List returned by Collections.singletonList(something) will result in UnsupportedOperationException.

Also, the capacity of the List returned by Collections.singletonList(something) will always be 1 unlike Arrays.asList(something) whose capacity will be the size of the backed array.

Solution 2 - Java

I would just add that the singletonlist is not backed by an array and just has a reference to that one item. Presumably, it would take less memory and can be significant depending on the number of lists you want to create.

Solution 3 - Java

The method Arrays.asList returns a fixed-size list backed by the specified array. The method returns an instance of ArrayList which is a private nested static class extending AbstractList and not java.util.ArrayList. This static class provides implementation of few methods e.g. set, indexOf, forEach, replaceAll etc. but when we invoke add it has no implementation of its own, rather method from AbstractList is invoked which throws java.lang.UnsupportedOperationException.

The Collections.singletonList returns an immutable list containing only the specified object and it is serializable as well.

On a side note, for immutable lists we generally use Collections.unmodifiableList which returns an unmodifiable view of the specified list.

List<String> srcList = Arrays.asList("Apple", "Mango", "Banana");
var fruits = new ArrayList<>(srcList);
var unmodifiableList = Collections.unmodifiableList(fruits);     
fruits.set(0, "Apricot");
var modFruit = unmodifiableList.get(0);
System.out.println(modFruit); // prints Apricot

An unmodifiable view collection is a collection that is unmodifiable and is also a view onto a backing collection. Note that changes to the backing collection might still be possible, and if they occur, they are visible through the unmodifiable view.

We can have a true immutable list in Java 10 and later. There are two ways to get truly unmodifiable list:

  1. var unmodifiableList = List.copyOf(srcList);
  2. var unmodifiableList = srcList.stream().collect(Collectors.toUnmodifiableList()); If any of these two variables are used value will still be "Apple" and not "Apricot".

As per doc of Java 10:

> The List.of and List.copyOf static factory methods provide a > convenient way to create unmodifiable lists. The List instances > created by these methods have the following characteristics: > > 1. They are unmodifiable. Elements cannot be added, removed, or replaced. Calling any mutator method on the List will always cause > UnsupportedOperationException to be thrown. However, if the contained > elements are themselves mutable, this may cause the List's contents to > appear to change. > 2. They disallow null elements. Attempts to create them with null elements result in NullPointerException. > 3. They are serializable if all elements are serializable. > 4. The order of elements in the list is the same as the order of the provided arguments, or of the elements in the provided array. > 5. They are value-based. Callers should make no assumptions about the identity of the returned instances. Factories are free to create new > instances or reuse existing ones. Therefore, identity-sensitive > operations on these instances (reference equality (==), identity hash > code, and synchronization) are unreliable and should be avoided. > 6. They are serialized as specified on the Serialized Form page.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionHoward GrimbergView Question on Stackoverflow
Solution 1 - JavaKumar AbhinavView Answer on Stackoverflow
Solution 2 - JavaapprenticeView Answer on Stackoverflow
Solution 3 - Javaakhil_mittalView Answer on Stackoverflow