AsList () vs Collections.singletonList ()

与 Collections.singletonList (something)相比,使用 Arrays.asList (something)创建包含一个条目的列表是否有优势(或者有很大的不同) ?后者也使返回的列表不可变。

104322 次浏览

Collections.singletonList(something)永恒不变,而 Arrays.asList(something)是一个固定大小的数组 List表示,其中 List 和 Array 在堆中联接。

Arrays.asList(something)允许对其执行 非结构性变化,这将反映到 List 和连接数组。它抛出 UnsupportedOperationException用于添加和删除元素,尽管您可以为特定索引设置元素。

对由 Collections.singletonList(something)返回的 List 所做的任何更改都将导致 UnsupportedOperationException

此外,由 Collections.singletonList(something)返回的 List 的容量将始终是 1,而 Arrays.asList(something)的容量将是备份数组的大小。

我要补充的是,singletonlist 没有数组支持,只有对该项的引用。据推测,它将占用更少的内存,并且取决于您想要创建的列表的数量,它可能非常重要。

方法 Arrays.asList返回由指定数组支持的固定大小的列表。该方法返回一个 ArrayList的实例,它是一个扩展 AbstractList私有嵌套静态类,而不是 java.util.ArrayList。这个静态类提供了一些方法的实现,比如 set, indexOf, forEach, replaceAll等等,但是当我们调用 add时,它没有自己的实现,而是调用了 AbstractList的方法,抛出了 java.lang.UnsupportedOperationException

Collections.singletonList返回一个仅包含指定对象的 不可变列表,并且它也是可序列化的。

值得注意的是,对于 不可变的列表,我们通常使用 Collections.unmodifiableList,它返回指定列表的不可修改的视图。

List<String> srcList = Arrays.asList("Apple", "Mango", "Banana");
var fruits = new ArrayList<>(srcList);
var unmodifiableList = Collections.unmodifiableList(fruits);
fruits.set(0, "Apricot");
var modFruit = unmodifiableList.get(0);
System.out.println(modFruit); // prints Apricot

不可修改的视图集合是不可修改的集合,也是后备集合的视图。请注意,对支持集合的更改仍然可能发生,如果发生了更改,则可以通过不可修改的视图看到它们。

我们可以在 爪哇10和更高版本中得到一个真正的不可变列表:

  1. var unmodifiableList = List.copyOf(srcList);
  2. 如果这两个变量中的任何一个被使用,值仍然是“苹果”而不是“杏”。

根据 爪哇10医生:

List.ofList.copyOf静态工厂方法提供了一个 创建不可修改列表的方便方法 这些方法所产生的影响具有以下特点:

  1. 它们是 无法改变。元素不能被添加、删除或替换。调用 List 上的任何 mutator 方法都会导致 但是,如果包含的 元素本身是可变的,这可能导致 List 的内容 似乎变了。
  2. 它们不允许空元素。尝试使用空元素创建它们将导致 NullPointerException
  3. 如果所有元素都是可序列化的,则它们是可序列化的。
  4. 列表中元素的顺序与提供的参数或提供的数组中元素的顺序相同。
  5. 他们是 value-based。调用方不应假设返回实例的标识。工厂可以自由创造新的 实例或重用现有的。因此,身份敏感 对这些实例的操作(引用相等(= =)、标识散列 代码和同步)是不可靠的,应该避免。
  6. 它们按照 连载表格页上指定的方式序列化。