Arrays.asList()vs Collections.singletonList()

How*_*erg 121 java collections

在Collections.singletonList(something)上使用Arrays.asList(something)制作包含一个项目的列表是否有优势(或许多不同之处)?后者使得返回的列表也是不可变的.

Kum*_*nav 183

Collections.singletonList(something)不可变的,而是一个Array Arrays.asList(something)的固定大小List表示,其中List和Array在堆中连接.

Arrays.asList(something)允许对其进行非结构性更改,这些更改将反映到List和连接数组中.UnsupportedOperationException虽然您可以为特定索引设置元素,但它会添加,删除元素.

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

此外,通过返回的列表的能力Collections.singletonList(something)永远是1不同Arrays.asList(something),其容量将是支持数组的大小.

  • 由于某种原因,IDE(Android Studio)告诉我应该使用“Collections.singletonList”。它真的知道使用它是安全的吗?你写道(根据我的测试,这是真的),如果它被修改(例如设置/删除),它可能会导致异常...... (3认同)

app*_*ice 59

我只想补充说,singletonlist没有数组支持,只有一个项目的引用.据推测,它会占用更少的内存,并且可能很重要,具体取决于您要创建的列表数量.


i_a*_*ero 9

该方法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
Run Code Online (Sandbox Code Playgroud)

不可修改的视图集合是一个不可修改的集合,也是一个支持集合的视图.请注意,可能仍然可以对支持集合进行更改,如果它们发生,则通过不可修改的视图可以看到它们.

我们可以在Java 10及更高版本中拥有一个真正的不可变列表.有两种方法可以获得真正不可修改的列表:

  1. var unmodifiableList = List.copyOf(srcList); =>打印Apple
  2. var unmodifiableList = srcList.stream().collect(Collectors.toUnmodifiableList()); =>打印Apple

按照文档Java的10:

List.ofList.copyOf静态工厂方法提供了一种方便的方式来创建不可修改的列表.这些方法创建的List实例具有以下特征:

  1. 它们是不可修改的.无法添加,删除或替换元素.在List上调用任何mutator方法总是会 UnsupportedOperationException引发抛出.但是,如果包含的元素本身是可变的,则可能导致List的内容看起来发生变化.
  2. 他们不允许使用null元素.尝试使用null元素创建它们会导致NullPointerException.
  3. 如果所有元素都可序列化,则它们是可序列化的.
  4. 列表中元素的顺序与提供的参数的顺序或提供的数组中的元素的顺序相同.
  5. 他们是value-based.调用者不应对返回实例的身份做出任何假设.工厂可以自由创建新实例或重用现有实例.因此,对这些实例的身份敏感操作(引用相等(==),标识哈希代码和同步)是不可靠的,应该避免.
  6. 它们按序列化表单页面上的指定进行序列化.