简体   繁体   中英

JDK's Arrays vs. Guava's ImmutableList

使用com.google.common.collect.ImmutableList.of(...)java.util.Arrays.asList(...)创建单行列表之间是否有优势?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM