Initialize List in Java in a Single Line

In this post, we will discuss various methods to initialize list in Java in a single line.


 

Java is often criticized for its verbosity. For example, creating a list containing n elements involves constructing it, storing it in a variable, invoking add() method on it n times, and then maybe wrapping it to make it unmodifiable:

 

 
In this post, we will discuss various methods to initialize list in a single expression.

 

1. Arrays.asList() –

Arrays.asList() returns a fixed-size list backed by the specified array. Since an array cannot be structurally modified, it is not possible to add elements to the list or remove elements from it. The list will throw an UnsupportedOperationException if any resize operation is performed on it.

If we need a List that can expand or shrink, we can use –

 

2. Java Collections –

Collections class consists of several static methods that operate on collections and return a new collection backed by a specified collection.

 

1. Collections.addAll()

Collections.addAll() adds all of the specified elements to the specified collection. Elements to be added may be specified individually or as an array. When elements are specified individually, this method provides a convenient way to add a few elements to an existing collection:

 

2. Collections.unmodifiableList()

Alternatively, one can populate a collection using a copy constructor from another collection. One such method is Collections.unmodifiableList() returns an unmodifiable view of the specified list. Any attempts to modify the returned list will result in an UnsupportedOperationException.

 

3. Collections.singletonList()

If we want a List containing only a single element, we can use Collections.singletonList() that returns an immutable list containing that element. The list will throw an UnsupportedOperationException if any modify operation is performed on it.

 

3. Double Brace Initialization –

Another alternative is to use “Double Brace Initialization”. This creates an anonymous inner class with just an instance initializer in it. This technique should be best avoided as it costs an extra class at each usage and it also holds hidden references to the enclosing instance and to any captured objects. This may cause memory leaks or problems with serialization.

 

4. Java 8 –

The Java 8 Stream API can be used to construct small lists by obtaining stream from static factory methods and accumulating the input elements into a new list using collectors. For example,

 

1. Collectors.toList()

Collectors.toList() returns a Collector that accumulates the input elements into a new List.

 

2. Collectors.toCollection()

The streams collectors make no guarantee on the type of the List returned by toList(). To ensure the returned List is ArrayList, we can use toCollection(Supplier) as shown below:

 

3. Collectors.collectingAndThen()

We could adapt a Collector to perform an additional finishing transformation. For example, we could adapt the toList() collector to always produce an unmodifiable list with:

 

5. Java 9 –

Java 9 made it convenient to create instances of list with small numbers of elements by providing Lists.of() static factory methods that creates compact, unmodifiable instances of it. For example,

Java 9 provides 12 overloaded versions of this method –

static List of()
static List of(E e1)1
static List of(E e1, E e2)
. . .
. . .
static List of(E e1, E e2, E e3, E e4, . . . E e8, E e9)
static List of(E e1, E e2, E e3, E e4, . . . E e8, E e9, E e10)
static List of(E… elements)

 
Note there is a var-args version which can handle any number of elements. Now the obvious question is why Java 9 has included so many extra methods when only var-args can suffice? The reason is there’s a subtle runtime performance advantage. The var-args version is likely to run slower than the overloadings that do not use varargs. This is because every invocation of a varargs method will cause an array allocation and initialization and not to forget GC overhead.

As per Javadoc, the List instances created by List.of() have the following characteristics:

  1. They are structurally immutable. Elements cannot be added, removed, or replaced. Calling any mutator method 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.
     

If we need a List that can expand or shrink, we can use –

 
Please note that unlike static methods on classes, static methods on interfaces are not inherited, so it will not be possible to invoke them via an implementing class, nor via an instance of the interface type.

 

6. Guava –

Guava also provides several static utility methods pertaining to List instances.

Refer: Initialize List using Guava in Java

 

7. Apache Commons Collections –

Apache Commons Collections ListUtils class provides unmodifiableList() that returns an unmodifiable list backed by the given list. It throws a NullPointerException if the given list is null and an UnsupportedOperationException if any modify operation is performed on it.

 
References: JEP 269: Convenience Factory Methods for Collections

 
Thanks for reading.




Please use ideone or C++ Shell or any other online compiler link to post code in comments.
Like us? Please spread the word and help us grow. Happy coding 🙂
 





Leave a Reply

Notify of
avatar
wpDiscuz