Java List.of 和 Arrays.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
What is the difference between List.of and Arrays.asList?
提问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.asList
returns a mutable list while the list returned by List.of
is 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.asList
allows null elements while List.of
doesn'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
contains
behaves 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.asList
returns a view of the passed array, so the changes to the array will be reflected in the list too. For List.of
this 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.of和Arrays.asList之间的区别
List.of
can be best used when data set is less and unchanged, whileArrays.asList
can be used best in case of large and dynamic data set.List.of
take 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. whileArrays.asList
take more overhead space because while initialization it creates more objects in heap.Collection returned by
List.of
is immutable and hence thread-safe while Collection returned byArrays.asList
is mutable and not thread safe. (Immutable collection instances generally consume much less memory than their mutable counterparts.)List.of
doesn't allow nullelements whileArrays.asList
allows nullelements.
List.of
最好在数据集较少且不变的Arrays.asList
情况下使用,而在大且动态数据集的情况下最好使用。List.of
占用很少的开销空间,因为它具有基于字段的实现并且消耗更少的堆空间,无论是在固定开销方面还是在每个元素的基础上。而Arrays.asList
占用更多的开销空间,因为在初始化时它会在堆中创建更多的对象。返回的集合
List.of
是不可变的,因此是线程安全的,而返回的集合Arrays.asList
是可变的,不是线程安全的。(不可变集合实例通常比可变集合实例消耗更少的内存。)List.of
不允许空元素而Arrays.asList
允许空元素。
回答by user1803551
The differences between Arrays.asList
and List.of
之间的差异Arrays.asList
和List.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.of
will 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
. 这包括诸如add、set和remove 之类的操作。但是,您可以更改列表中对象的内容(如果对象不是不可变的),因此列表不是“完全不可变的”。
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.asList
is 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.of
and any collection since Java 1.5 do not allow null
as an element. Attempting to pass null
as an element or even a lookup will result in a NullPointerException
.
List.of
并且自 Java 1.5 以来的任何集合都不允许null
作为元素。尝试null
作为元素传递甚至查找将导致NullPointerException
.
Since Arrays.asList
is a collection from 1.2 (the Collections Framework), it allows null
s.
由于Arrays.asList
是 1.2(集合框架)的集合,因此它允许null
s.
listOf.contains(null); // NullPointerException
unmodif.contains(null); // allowed
asList.contains(null); // allowed
Serialized form
序列化形式
Since List.of
has 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.asList
internally calls new ArrayList
, which guarantees reference inequality.
Arrays.asList
内部调用new ArrayList
,这保证了引用不等式。
List.of
depends 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.of
is 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.of
implementations 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.of
is 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 UnmodifiableList
wrapper plus some pennies. Ultimately, the savings in the HashSet
equivalent are more convincing.
这会创建 2 个列表以及其他开销。在空间方面,您可以节省UnmodifiableList
包装纸和一些便士。最终,HashSet
等价物的节省更具说服力。
Conclusion time: use List.of
when you want a list that doesn't change and Arrays.asList
when 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::of
and Arrays::asList
differ:
除了上述答案之外,还有一些操作是List::of
和Arrays::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 | ? | ? | ?? | ?? |
+----------------------+---------------+----------+----------------+---------------------+
- ?? means the method is supported
- ? means that calling this method will throw an UnsupportedOperationException
- ?? 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
- ?? 表示支持该方法
- ? 意味着调用此方法将抛出 UnsupportedOperationException
- ?? 表示仅当方法的参数不会导致突变时才支持该方法,例如 Collections.singletonList("foo").retainAll("foo") 可以,但 Collections.singletonList("foo").retainAll("bar")抛出 UnsupportedOperationException
More about Collections::singletonList Vs. List::of