The Arrays.asList() method in Java provides a convenient way to convert between arrays and Lists. However, the returned List has limitations that developers should understand.

This comprehensive guide will cover all aspects of using Arrays.asList() effectively:

1. How Arrays.asList() Works

Internally, Arrays.asList() converts the array into a List implementation called Arrays.ArrayList. This ArrayList wraps the original array and directs all operations to it.

Some key characteristics of this List:

  • It has a fixed size equal to the array length.
  • It does not support adding/removing elements.
  • The set() method is not supported.
  • It maintains a direct reference to the original array.

This lightweight List avoids copying the array, saving time and memory. But these limitations must be considered.

2. Common Operations

Here are examples of common operations that can be performed on the List:

Iterate Over Elements

Since the List size matches the array length, iterating over elements is simple:

String[] arr = {"a", "b", "c"};
List<String> list = Arrays.asList(arr);

for(String s : list) {
  System.out.println(s); //prints a, b, c
}

Searching for an Element

The List can leverage the ArrayList contains() method for searching:

if(list.contains("b")) {
  //found element
}

The indexOf() method can also be used to get an element‘s position.

Sorting Elements

The Collections utility class provides sorting support:

Collections.sort(list); //sorts arr array

Converting Back to an Array

The List provides a toArray() method to recreate the original array:

String[] arr2 = list.toArray(new String[0]); //arr2 contains arr elements

3. Limitations

While common read operations are supported, the List has constraints regarding write operations:

Fixed Size

Adding or removing elements is not permitted:

list.add("d"); //throws UnsupportedOperationException
list.remove(0); //throws UnsupportedOperationException

No Index Assignment

Setting specific indexes through set() is prohibited:

list.set(0, "d"); //throws UnsupportedOperationException 

Array Reference Semantics

The returned List directly references the original array. If the array is garbage collected, the List may fail:

int[] array = {1, 2, 3};
List<Integer> list = Arrays.asList(array); 

array = null; //array now eligible for GC

int number = list.get(0); //may throw NullPointerException

4. Alternatives to Arrays.asList()

Since Arrays.asList() has modifcation restrictions, alternatives like ArrayList are often preferrable:

ArrayList

Integer[] array = {1, 2, 3};

ArrayList<Integer> list = new ArrayList<>(Arrays.asList(array));  

Benefits:

  • Full add/remove support
  • Stable even if original array is GC‘ed
  • Additional ArrayList methods

Drawback – Changes do not propagate to the array.

LinkedList

Performs well for frequent insertions/deletions:

LinkedList<Integer> linkedList = new LinkedList<>(Arrays.asList(array));

CopyOnWriteArrayList

Thread-safe variant of ArrayList:

CopyOnWriteArrayList<Integer> threadSafeList = 
  new CopyOnWriteArrayList<>(Arrays.asList(array));  

Comparison Between List Implementations

Operation Arrays.asList ArrayList LinkedList
Get Fast Fast Slow
Set Not supported Fast Slow
Add Not supported Fast Fast
Remove Not supported Fast Fast
Iteration Fast Fast Slow

5. Multi-dimensional Arrays

The asList() method also works for multi-dimensional arrays:

int[][] twoDarray = {{1, 2}, {3, 4}};
List<int[]> list = Arrays.asList(twoDarray);

However, the limitations still apply – the List size is fixed and elements cannot be set/added/removed.

6. Usage with Primitive Types

Arrays.asList() cannot be directly used with primitive types like int[] and long[]. However, the array can be converted to a boxed Integer/Long array:

int[] prim = {1, 2, 3};
Integer[] wrapper = ArrayUtils.toObject(prim);

List<Integer> intList = Arrays.asList(wrapper);

Apache Commons Lang provides the ArrayUtils class. The auto-boxing helps bridge between primitive arrays and object-accepting methods like asList.

7. Custom Object Arrays

The asList() method can convert arrays of custom classes to Lists as well:

class Person {
  String name;  
  int age;

  //constructor, getters 
}

Person[] people = {new Person(...), new Person(...)}; 

List<Person> peopleList = Arrays.asList(people);

Standard List operations can then be performed on the custom Person objects.

8. Thread-safety

The List returned by Arrays.asList() is not thread-safe for multi-threaded access. Concurrent modification by threads would cause exceptions or data corruption.

Consider the thread-safe CopyOnWriteArrayList instead:

CopyOnWriteArrayList<String> threadSafeList =
  new CopyOnWriteArrayList<>(Arrays.asList(array)); 

9. Use Cases of Arrays.asList()

Read-Only Access

When array modifications are not needed, avoiding superfluous ArrayList creation improves efficiency.

Bridging Between Arrays and Lists

It provides a handy way to leverage List utilities on an existing array.

Lightweight Alternative to ArrayList

The returned List avoids copying array contents unnecessarily.

10. When to Avoid Arrays.asList()

Modification Required

For mutable Lists, alternatives like ArrayList should be used.

Unknown Lifetime of Passed Arrays

If the array can be GC‘ed unexpectedly, exceptions may occur.

Multi-threaded Access

Thread-safety risks arise without external synchronization.

Summary

  • Arrays.asList() converts arrays to List views.
  • It directly references arrays, avoiding copying.
  • Modifying the List throws exceptions.
  • Alternatives like ArrayList add flexibility.
  • Usage with primitives/multi-dimensional arrays needs attention.
  • Thread-safety should be managed explicitly.

Similar Posts