Java List.of 和 A​​rrays.asList 有什么区别?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/46579074/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 02:24:53  来源:igfitidea点击:

What is the difference between List.of and Arrays.asList?

javalistjava-9

提问by

Java 9 introduced new factory methods for lists, List.of:

Java 9 为列表引入了新的工厂方法List.of

List<String> strings = List.of("first", "second");

What's the difference between the previous and the new option? That is, what's the difference between this:

旧选项和新选项有什么区别?也就是说,这之间有什么区别:

Arrays.asList(1, 2, 3);

and this:

和这个:

List.of(1, 2, 3);

采纳答案by ZhekaKozlov

Arrays.asListreturns a mutable list while the list returned by List.ofis immutable:

Arrays.asList返回一个可变列表,而返回的列表List.of不可变的

List<Integer> list = Arrays.asList(1, 2, null);
list.set(1, 10); // OK

List<Integer> list = List.of(1, 2, 3);
list.set(1, 10); // Fails with UnsupportedOperationException

Arrays.asListallows null elements while List.ofdoesn't:

Arrays.asList允许空元素而List.of不允许:

List<Integer> list = Arrays.asList(1, 2, null); // OK
List<Integer> list = List.of(1, 2, null); // Fails with NullPointerException

containsbehaves differently with nulls:

contains与空值的行为不同:

List<Integer> list = Arrays.asList(1, 2, 3);
list.contains(null); // Returns false

List<Integer> list = List.of(1, 2, 3);
list.contains(null); // Fails with NullPointerException

Arrays.asListreturns a view of the passed array, so the changes to the array will be reflected in the list too. For List.ofthis is not true:

Arrays.asList返回传递数组的视图,因此对数组的更改也将反映在列表中。因为List.of这不是真的:

Integer[] array = {1,2,3};
List<Integer> list = Arrays.asList(array);
array[1] = 10;
System.out.println(list); // Prints [1, 10, 3]

Integer[] array = {1,2,3};
List<Integer> list = List.of(array);
array[1] = 10;
System.out.println(list); // Prints [1, 2, 3]

回答by Mohit Tyagi

Let summarize the differences between List.ofand Arrays.asList

让我们总结一下List.ofArrays.asList之间的区别

  1. List.ofcan be best used when data set is less and unchanged, while Arrays.asListcan be used best in case of large and dynamic data set.

  2. List.oftake very less overhead space because it has field-based implementation and consume less heap space, both in terms of fixed overhead and on a per-element basis. while Arrays.asListtake more overhead space because while initialization it creates more objects in heap.

  3. Collection returned by List.ofis immutable and hence thread-safe while Collection returned by Arrays.asListis mutable and not thread safe. (Immutable collection instances generally consume much less memory than their mutable counterparts.)

  4. List.ofdoesn't allow nullelements while Arrays.asListallows nullelements.

  1. List.of最好在数据集较少且不变的Arrays.asList情况下使用,而在大且动态数据集的情况下最好使用。

  2. List.of占用很少的开销空间,因为它具有基于字段的实现并且消耗更少的堆空间,无论是在固定开销方面还是在每个元素的基础上。而Arrays.asList占用更多的开销空间,因为在初始化时它会在堆中创建更多的对象。

  3. 返回的集合List.of是不可变的,因此是线程安全的,而返回的集合Arrays.asList是可变的,不是线程安全的。(不可变集合实例通常比可变集合实例消耗更少的内存。)

  4. List.of不允许元素而Arrays.asList允许元素。

回答by user1803551

The differences between Arrays.asListand List.of

之间的差异Arrays.asListList.of

See the JavaDocsand this talkby Stuart Marks (or previous versions of it).

请参阅JavaDocs和Stuart Marks 的这个演讲(或其以前的版本)。

I'll be using the following for the code examples:

我将使用以下代码示例:

List<Integer> listOf = List.of(...);
List<Integer> asList = Arrays.asList(...);
List<Integer> unmodif = Collections.unmodifiableList(asList);

Structural immutability (Or: unmodifiability)

结构不变性(或:不可修改性)

Any attempt to structurallychange List.ofwill result in an UnsupportedOperationException. That includes operations such as add, setand remove. You can, however, change the contents of the objects in the list (if the objects are not immutable), so the list is not "completely immutable".

任何在结构上进行更改的尝试List.of都将导致UnsupportedOperationException. 这包括诸如addsetremove 之类的操作。但是,您可以更改列表中对象的内容(如果对象不是不可变的),因此列表不是“完全不可变的”。

This is the same fate for unmodifiable lists created with Collections.unmodifiableList. Only this list is a viewof the original list, so it can change if you change the original list.

对于使用Collections.unmodifiableList. 只有这个列表是原始列表的视图,因此如果您更改原始列表,它会发生变化。

Arrays.asListis not completely immutable, it does not have a restriction on set.

Arrays.asList不是完全不可变的,它对 没有限制set

listOf.set(1, "a");  // UnsupportedOperationException
unmodif.set(1, "a"); // UnsupportedOperationException
asList.set(1, "a");  // modified unmodif! unmodif is not truly unmodifiable

Similarly, changing the backing array (if you hold it) will change the list.

同样,更改后备数组(如果您持有它)将更改列表。

Structural immutability comes with many side-effects related to defensive coding, concurrency and security which are beyond the scope of this answer.

结构不变性带来了许多与防御性编码、并发性和安全性相关的副作用,这些超出了本答案的范围。

Null hostility

零敌意

List.ofand any collection since Java 1.5 do not allow nullas an element. Attempting to pass nullas an element or even a lookup will result in a NullPointerException.

List.of并且自 Java 1.5 以来的任何集合都不允许null作为元素。尝试null作为元素传递甚至查找将导致NullPointerException.

Since Arrays.asListis a collection from 1.2 (the Collections Framework), it allows nulls.

由于Arrays.asList是 1.2(集合框架)的集合,因此它允许nulls.

listOf.contains(null);  // NullPointerException
unmodif.contains(null); // allowed
asList.contains(null);  // allowed

Serialized form

序列化形式

Since List.ofhas been introduced in Java 9 and the lists created by this method have their own (binary) serialized form, they cannot be deserialized on earlier JDK versions (no binary compatibility). However, you can de/serialize with JSON, for example.

由于List.of已在 Java 9 中引入,并且此方法创建的列表具有自己的(二进制)序列化形式,因此无法在早期 JDK 版本上反序列化(无二进制兼容性)。但是,例如,您可以使用 JSON 反序列化/序列化。

Identity

身份

Arrays.asListinternally calls new ArrayList, which guarantees reference inequality.

Arrays.asList内部调用new ArrayList,这保证了引用不等式。

List.ofdepends on internal implementation. The instances returned can have reference equality, but since this is not guaranteed you can not rely on it.

List.of取决于内部实现。返回的实例可以具有引用相等性,但由于不能保证您不能依赖它。

asList1 == asList2; // false
listOf1 == listOf2; // true or false

Worth mentioning that lists are equal (via List.equals) if they contain the same elements in the same order, regardless of how they were created or what operations they support.

值得一提的是,如果列表List.equals以相同的顺序包含相同的元素,则列表是相等的(通过),无论它们是如何创建的或它们支持什么操作。

asList.equals(listOf); // true i.f.f. same elements in same order

Implementation (warning: details can change over versions)

实施(警告:细节可能会随着版本的变化而变化)

If the number of elements in the list of List.ofis 2 or less, the elements are stored in fields of a specialized (internal) class. An example is the list that stores 2 elements (partial source):

如果列表中的元素数List.of为 2 或更少,则元素存储在专用(内部)类的字段中。一个例子是存储 2 个元素的列表(部分来源):

static final class List2<E> extends AbstractImmutableList<E> {
    private final E e0;
    private final E e1;

    List2(E e0, E e1) {
        this.e0 = Objects.requireNonNull(e0);
        this.e1 = Objects.requireNonNull(e1);
    }
}

Otherwise they are stored in an array in a similar fashion to Arrays.asList.

否则,它们以与 类似的方式存储在数组中Arrays.asList

Time and Space efficiency

时空效率

The List.ofimplementations which are field-based (size<2) perform slightly faster on some operations. As examples, size()can return a constant without fetching the array length, and contains(E e)does not require iteration overhead.

List.of其是基于场的(大小<2)实施方式中的一些操作速度稍快执行。例如,size()可以在不获取数组长度的情况下返回一个常量,并且contains(E e)不需要迭代开销。

Constructing an unmodifiable list via List.ofis also faster. Compare the above constructor with 2 reference assignments (and even the one for arbitrary amount of elements) to

通过构建不可修改的列表List.of也更快。将上述构造函数与 2 个引用赋值(甚至是任意数量元素的赋值)进行比较

Collections.unmodifiableList(Arrays.asList(...));

which creates 2 lists plus other overhead. In terms of space, you save the UnmodifiableListwrapper plus some pennies. Ultimately, the savings in the HashSetequivalent are more convincing.

这会创建 2 个列表以及其他开销。在空间方面,您可以节省UnmodifiableList包装纸和一些便士。最终,HashSet等价物的节省更具说服力。



Conclusion time: use List.ofwhen you want a list that doesn't change and Arrays.asListwhen you want a list that can change (as shown above).

结束时间:List.of当你想要一个不会改变Arrays.asList的列表以及当你想要一个可以改变的列表时使用(如上所示)。

回答by Vishwa Ratna

Apart from the above answers there are certain operations on which both List::ofand Arrays::asListdiffer:

除了上述答案之外,还有一些操作是List::ofArrays::asList不同的:

+----------------------+---------------+----------+----------------+---------------------+
|      Operations      | SINGLETONLIST | LIST::OF | ARRAYS::ASLIST | JAVA.UTIL.ARRAYLIST |
+----------------------+---------------+----------+----------------+---------------------+
|          add         |       ?       |     ?    |        ?       |          ??          |
+----------------------+---------------+----------+----------------+---------------------+
|        addAll        |       ?       |     ?    |        ?       |          ??          |
+----------------------+---------------+----------+----------------+---------------------+
|         clear        |       ?       |     ?    |        ?       |          ??          |
+----------------------+---------------+----------+----------------+---------------------+
|        remove        |       ?       |     ?    |        ?       |          ??          |
+----------------------+---------------+----------+----------------+---------------------+
|       removeAll      |       ??       |     ?    |        ??       |          ??          |
+----------------------+---------------+----------+----------------+---------------------+
|       retainAll      |       ??       |     ?    |        ??       |          ??          |
+----------------------+---------------+----------+----------------+---------------------+
|      replaceAll      |       ?       |     ?    |        ??       |          ??          |
+----------------------+---------------+----------+----------------+---------------------+
|          set         |       ?       |     ?    |        ??       |          ??          |
+----------------------+---------------+----------+----------------+---------------------+
|         sort         |       ??       |     ?    |        ??       |          ??          |
+----------------------+---------------+----------+----------------+---------------------+
|  remove on iterator  |       ?       |     ?    |        ?       |          ??          |
+----------------------+---------------+----------+----------------+---------------------+
| set on list-iterator |       ?       |     ?    |        ??       |          ??          |
+----------------------+---------------+----------+----------------+---------------------+
  1. ?? means the method is supported
  2. ? means that calling this method will throw an UnsupportedOperationException
  3. ?? means the method is supported only if the method's arguments do not cause a mutation, e.g. Collections.singletonList("foo").retainAll("foo") is OK but Collections.singletonList("foo").retainAll("bar")throws an UnsupportedOperationException
  1. ?? 表示支持该方法
  2. ? 意味着调用此方法将抛出 UnsupportedOperationException
  3. ?? 表示仅当方法的参数不会导致突变时才支持该方法,例如 Collections.singletonList("foo").retainAll("foo") 可以,但 Collections.singletonList("foo").retainAll("bar")抛出 UnsupportedOperationException

More about Collections::singletonList Vs. List::of

更多关于Collections::singletonList 与。清单