Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JDK's Arrays vs. Guava's ImmutableList

Is there advanteges between using one-line list creation with com.google.common.collect.ImmutableList.of(...) and java.util.Arrays.asList(...) ?

like image 721
Michael Z Avatar asked Jun 19 '13 19:06

Michael Z


People also ask

Is ArrayList immutable in Java?

No, you cannot make the elements of an array immutable. But the unmodifiableList() method of the java. util. Collections class accepts an object of the List interface (object of implementing its class) and returns an unmodifiable form of the given object.

Is Unmodifiable list immutable?

A collection is considered unmodifiable if elements cannot be added, removed, or replaced. However, an unmodifiable collection is only immutable if the elements contained in the collection are immutable.

Are arrays asList Unmodifiable?

asList() method. Arrays. asList() method returns a fixed-size list backed by the specified array. Since an array cannot be structurally modified, it is impossible to add elements to the list or remove elements from it.

What is the difference between arrays asList and list of?

Collection returned by List. of is immutable and hence thread-safe while Collection returned by Arrays. asList is mutable and not thread safe. (Immutable collection instances generally consume much less memory than their mutable counterparts.)


1 Answers

The Arrays.asList(...) method provides a list view of the underlying array.

Integer[] numbers = {17, 42, 2001};
List<Integer> list = Arrays.asList(numbers);
System.out.println(list.get(0)); // Prints 17.
list.remove(0);  // throws.
numbers[0] = 1;
System.out.println(list.get(0)); // Prints 1.
list.set(0, 17);
System.out.println(numbers[0]);  // Prints 17.

Arrays.asList has very little to do with immutability. The returned list cannot have elements added or removed, but it can be changed, and changes change the underlying array. In fact the class of the returned list is a special one that uses the array for storage. It's similar to this:

List<Integer> integers = new ArrayList<>();
integers.add(17);
integers.add(42);
integers.add(2001);
List<Integer> unmodifiable = Collections.unmodifiableList(integers);
unmodifiable.set(0, 1);                  // throws.
unmodifiable.remove(0);                  // throws.
unmodifiable.add(867_5309);              // throws.
integers.set(0, 1)                       // okay.
System.out.println(unmodifiable.get(0)); // Prints 1.

That is safe only if one throws the original list away, as in this map example. Since map goes out of scope, nothing can change the underlying map of the unmodifiable map CAPITALS.

public static final Map<String, String> CAPITALS;
static {
    Map<String, String> map = new HashMap<>();
    map.put("USA", "Washington, DC");
    map.put("England", "London");
    // ...
    CAPITALS = Collections.unmodifiableMap(map);
}

Guava's ImmutableList creates a new copy of the data if the original data is not stored immutably itself. Quoting its docs:

It is useful to remember that ImmutableXXX.copyOf attempts to avoid copying the data when it is safe to do so — the exact details are unspecified, but the implementation is typically “smart”.

So, Guava has its immutable collections independant of their origins.

List<Integer> original = new ArrayList<>();
original.add(1);
original.add(2);
original.add(3);
ImmutableList<Integer> immutable = ImmutableList.copyOf(original);
immutable.set(0, 42);  // throws.
System.out.println(immutable.get(0)); // Prints 1.
original.set(0, 42);   // fine.
System.out.println(immutable.get(0)); // Prints 1.
ImmutableList<Integer> copy = ImmutableList.copyOf(immutable);
    // Shares immutable's data.
like image 57
Eric Jablow Avatar answered Oct 09 '22 00:10

Eric Jablow