JDK的Arrays与Guava的ImmutableList

时间:2013-06-19 19:58:34

标签: arrays list java guava

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

1 个答案:

答案 0 :(得分:25)

Arrays.asList(...)方法提供了基础数组的列表视图

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与不变性无关。返回的列表不能添加或删除元素,但可以更改它,并且更改会更改基础数组。实际上,返回列表的类是一个使用该数组进行存储的特殊类。它与此类似:

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.

只有在抛出原始列表时才会安全,就像在这个地图示例中一样。由于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的ImmutableList会创建一个新的数据副本。引用其docs

  

有必要记住,ImmutableXXX.copyOf会在安全的情况下尝试避免复制数据 - 具体细节未指定,但实现通常是“智能”。

因此,Guava的不可变集合与其起源无关。

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.
相关问题