Generic Top

Get started with Spring 5 and Spring Boot 2, through the Learn Spring course:

>> CHECK OUT THE COURSE

1. Overview

List is a commonly used collection type when we work with Java.

As we know, we can easily initialize a List in one line. For example, when we want to initialize a List with only one single element, we can use the Arrays.asList() method or the Collections.singletonList() method.

In this tutorial, we'll discuss the differences between these two methods. Then, for simplicity, we'll use unit test assertions to verify whether some operations behave as expected.

2. The Arrays.asList() Method

First of all, the Arrays.asList() method returns a fixed-size list.

Any structural changes will throw UnsupportedOperationException, for example, adding new elements to the list or removing elements from the list. Now, let's check it with a test:

List<String> arraysAsList = Arrays.asList("ONE");
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(
    () -> arraysAsList.add("TWO")
);

The test passes if we give it a run. In the code above, we've used Assertj's exception assertion to verify if UnsupportedOperationException is thrown when we try to add a new element to the list.

Even though can't we call add() or remove() operations on the list, we can change the elements in the list using the set() method:

arraysAsList.set(0, "A brand new string");
assertThat(arraysAsList.get(0)).isEqualTo("A brand new string");

This time, we set the element in the list with a new String object. If we execute the test, it passes.

Finally, let's discuss the relationship between the array of the Arrays.asList() method and the returned list.

As the method name implies, this method makes an array work as a List. Let's understand what “making an array work as a List” means.

The Arrays.asList() method returns a List object, which is backed by the given array. That is to say, the method doesn't copy the elements from the array to the new List object. Instead, the method provides a List view on the given array. Therefore, any changes we make to the array will be visible in the returned list. Similarly, changes made to the list will be visible in the array too:

String[] theArray = new String[] { "ONE", "TWO" };
List<String> theList = Arrays.asList(theArray);
//changing the list, the array is changed too
theList.set(0, "ONE [changed in list]");
assertThat(theArray[0]).isEqualTo("ONE [changed in list]");

//changing the array, the list is changed too
theArray[1] = "TWO [changed in array]";
assertThat(theList.get(1)).isEqualTo("TWO [changed in array]");

The test passes. So for the array and the returned list, if we've made some changes on one side, the other side is changed as well.

3. The Collections.singletonList() Method

First, the list returned by the singletonList() method has only one element. Unlike the Arrays.asList() method, singletonList() returns an immutable list.

In other words, both structural and non-structural changes aren't allowed to be made on the list returned by singletonList(). A test can quickly illustrate this:

List<String> singletonList = Collections.singletonList("ONE");
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(
    () -> singletonList.add("TWO")
);
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(
    () -> singletonList.set(0, "A brand new string")
);

If we run the test, it passes. So, no matter whether we are adding an element to the list or changing the element in the list, it throws UnsupportedOperationException.

It's worth mentioning that if we have a look at the source code of the returned list class, unlike other List implementations, the single element in the returned list isn't stored in an array or any other complex data structure. Instead, the list holds the element object directly:

private static class SingletonList<E> extends AbstractList<E> implements RandomAccess, Serializable {
    ...
    private final E element;

    SingletonList(E obj) {element = obj;}
    ...
}

Therefore, it would take less memory.

4. Short Summary

Finally, let's summarize characteristics of the Arrays.asList() method and the Collections.singletonList() method in a table to get a better overview:

Arrays.asList() Collections.singletonList()
Structural Changes Not Allowed Not Allowed
 Non-Structural Changes  Allowed Not Allowed
Data Structure Backed by the array Hold the element directly

5. Conclusion

In this quick article, we've discussed the Arrays.asList() method and the Collections.singletonList() method.

When we want to initialize a fixed-size list with only one single element, we can consider using the Collections.singletonList() method. However, if changing the element in the returned list is required, we can choose the Arrays.asList() method.

As always, the full source code of the examples is available over on GitHub.

Generic bottom

Get started with Spring 5 and Spring Boot 2, through the Learn Spring course:

>> CHECK OUT THE COURSE
Generic footer banner
guest
0 Comments
Inline Feedbacks
View all comments