【问题标题】:JDK's Arrays vs. Guava's ImmutableListJDK 的数组与 Guava 的 ImmutableList
【发布时间】:2013-06-16 12:23:43
【问题描述】:

使用com.google.common.collect.ImmutableList.of(...)java.util.Arrays.asList(...) 创建单行列表有什么好处吗?

【问题讨论】:

    标签: arrays list java guava


    【解决方案1】:

    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.
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-14
      • 2011-04-13
      相关资源
      最近更新 更多