Java 9为列表引入了一种新的工厂方法List.of
:
List<String> strings = List.of("first", "second");
Run Code Online (Sandbox Code Playgroud)
前一个和新选项有什么区别?也就是说,这有什么区别:
Arrays.asList(1, 2, 3);
Run Code Online (Sandbox Code Playgroud)
还有这个:
List.of(1, 2, 3);
Run Code Online (Sandbox Code Playgroud)
Zhe*_*lov 145
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
Run Code Online (Sandbox Code Playgroud)
Arrays.asList
允许null元素List.of
而不:
List<Integer> list = Arrays.asList(1, 2, null); // OK
List<Integer> list = List.of(1, 2, null); // Fails with NullPointerException
Run Code Online (Sandbox Code Playgroud)
contains
行为与null不同:
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
Run Code Online (Sandbox Code Playgroud)
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]
Run Code Online (Sandbox Code Playgroud)
use*_*551 25
Arrays.asList
和之间的区别List.of
请参阅JavaDocs和Stuart Marks(或其先前版本)的演讲.
我将使用以下代码示例:
List<Integer> listOf = List.of(...);
List<Integer> asList = Arrays.asList(...);
List<Integer> unmodif = Collections.unmodifiableList(asList);
Run Code Online (Sandbox Code Playgroud)
任何结构改变的尝试List.of
都会导致UnsupportedOperationException
.这包括添加,设置和删除等操作.你可以,但是,改变对象的内容在列表中(如果对象并非一成不变的),所以列表不是"完全不可改变的".
对于使用创建的不可修改列表,这是相同的命运Collections.unmodifiableList
.只有此列表是原始列表的视图,因此如果更改原始列表,它可以更改.
Arrays.asList
不是完全不可变的,它没有限制set
.
listOf.set(1, "a"); // UnsupportedOperationException
unmodif.set(1, "a"); // UnsupportedOperationException
asList.set(1, "a"); // modified unmodif! unmodif is not truly unmodifiable
Run Code Online (Sandbox Code Playgroud)
同样,更改后备阵列(如果您持有)将更改列表.
结构不变性伴随着许多与防御性编码,并发性和安全性相关的副作用,超出了本答案的范围.
List.of
自Java 1.5以来的任何集合都不允许null
作为元素.尝试null
作为元素或甚至查找传递将导致a NullPointerException
.
由于Arrays.asList
是1.2(集合框架)的集合,它允许null
s.
listOf.contains(null); // NullPointerException
unmodif.contains(null); // allowed
asList.contains(null); // allowed
Run Code Online (Sandbox Code Playgroud)
由于List.of
已经在Java 9中引入并且由此方法创建的列表具有它们自己的(二进制)序列化形式,因此它们不能在早期的JDK版本上反序列化(没有二进制兼容性).但是,您可以使用JSON进行de/serialize.
Arrays.asList
内部调用new ArrayList
,保证参考不等式.
List.of
取决于内部实施.返回的实例可以具有引用相等性,但由于无法保证您不能依赖它.
asList1 == asList2; // false
listOf1 == listOf2; // true or false
Run Code Online (Sandbox Code Playgroud)
值得一提的是,如果列表List.equals
包含相同顺序的相同元素,则它们是相同的(via ),无论它们是如何创建的,还是它们支持的操作.
asList.equals(listOf); // true i.f.f. same elements in same order
Run Code Online (Sandbox Code Playgroud)
如果列表中的元素数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);
}
}
Run Code Online (Sandbox Code Playgroud)
否则它们以类似的方式存储在数组中Arrays.asList
.
在List.of
其是基于字段的实现(大小<2)上的一些操作速度稍快执行.例如,size()
可以在不获取数组长度的情况下返回常量,并且contains(E e)
不需要迭代开销.
构建不可修改的列表List.of
也更快.将上面的构造函数与2个引用赋值(甚至是任意数量的元素的赋值)进行比较
Collections.unmodifiableList(Arrays.asList(...));
Run Code Online (Sandbox Code Playgroud)
这会创建2个列表以及其他开销.在空间方面,您可以保存UnmodifiableList
包装器和一些便士.最终,HashSet
相当于节省的成本更具说服力.
结束时间:List.of
当您想要一个不会更改Arrays.asList
的列表以及何时需要可以更改的列表时使用(如上所示).
Moh*_*agi 14
让我们总结一下List.of和Arrays.asList之间的区别
List.of
当数据集较少且不变时,Arrays.asList
可以最好地使用,而在大型和动态数据集的情况下可以最佳地使用.
List.of
占用非常少的开销空间,因为它具有基于字段的实现,并且在固定开销和每个元素的基础上消耗更少的堆空间.而Arrays.asList
需要更多开销的空间,因为当初始化它在堆中创建多个对象.
返回的集合List.of
是不可变的,因此线程安全,而返回的Collection Arrays.asList
是可变的而不是线程安全的.(不可变集合实例通常比其可变对应实例消耗更少的内存.)
List.of
允许null元素时Arrays.asList
不允许null元素.
Vis*_*tna 10
除了上述答案之外,还有一些操作是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 | ? | ? | ?? | ?? |
+----------------------+---------------+----------+----------------+---------------------+
Run Code Online (Sandbox Code Playgroud)
更多关于Collections::singletonList 与。清单
小智 10
Arrays.asList(1, 2, 3);
将创建一个固定大小的 列表:
public static void main(String[] args) {
List<Integer> asList = Arrays.asList(1, 2, 3, 4, 5);
asList.add(6); // java.lang.UnsupportedOperationException
asList.remove(0); // java.lang.UnsupportedOperationException
asList.set(0, 0); // allowed
}
Run Code Online (Sandbox Code Playgroud)
列表 (1, 2, 3);
将创建一个不可变(Java 9)/不可修改(Java 11) 列表:
public static void main(String[] args) {
List<Integer> listOf = List.of(1, 2, 3, 4, 5);
listOf.add(6); // java.lang.UnsupportedOperationException
listOf.remove(0); // java.lang.UnsupportedOperationException
listOf.set(0, 0); // java.lang.UnsupportedOperationException
}
Run Code Online (Sandbox Code Playgroud)