List.of 和 Arrays.asList 之间有什么区别?Arrays.asList 和 List.of 之间的区别
Java 9 引入了列表的新工厂方法,List.of
:
List<String> strings = List.of("first", "second");
以前选项和新选项有什么区别?也就是说,这有什么区别:
Arrays.asList(1, 2, 3);
和这个:
List.of(1, 2, 3);
Java 9 引入了列表的新工厂方法,List.of
:
List<String> strings = List.of("first", "second");
以前选项和新选项有什么区别?也就是说,这有什么区别:
Arrays.asList(1, 2, 3);
和这个:
List.of(1, 2, 3);
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
允许空元素,但不允许:List.of
List<Integer> list = Arrays.asList(1, 2, null); // OK
List<Integer> list = List.of(1, 2, null); // Fails with NullPointerException
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
返回所传递数组的视图,因此对数组的更改也将反映在列表中。因为事实并非如此: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]
Arrays.asList
和 List.of
之间的区别
请参阅JavaDocs和Stuart Marks的演讲(或其以前的版本)。
我将在代码示例中使用以下内容:
List<Integer> listOf = List.of(...);
List<Integer> asList = Arrays.asList(...);
List<Integer> unmodif = Collections.unmodifiableList(asList);
任何在结构上进行更改的尝试都将导致 .这包括添加,设置和删除等操作。但是,您可以更改列表中对象的内容(如果对象不是不可变的),因此列表不是“完全不可变的”。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
同样,更改后备数组(如果按住它)将更改列表。
结构不变性带来了许多与防御性编码,并发性和安全性相关的副作用,这些副作用超出了本答案的范围。
List.of
自 Java 1.5 以来,任何集合都不允许作为元素。尝试作为元素传递甚至查找将导致 .null
null
NullPointerException
由于 是 1.2(集合框架)中的集合,因此它允许 s。Arrays.asList
null
listOf.contains(null); // NullPointerException
unmodif.contains(null); // allowed
asList.contains(null); // allowed
由于在 Java 9 中已经引入,并且此方法创建的列表具有自己的(二进制)序列化形式,因此无法在早期的 JDK 版本上反序列化它们(没有二进制兼容性)。但是,例如,您可以使用 JSON 进行反序列化。List.of
Arrays.asList
内部调用 ,这保证了引用不等式。new ArrayList
List.of
取决于内部实现。返回的实例可以具有引用相等性,但由于不能保证这一点,因此您不能依赖它。
asList1 == asList2; // false
listOf1 == listOf2; // true or false
值得一提的是,如果列表以相同的顺序包含相同的元素,则列表是相等的(通过List.equals
),无论它们是如何创建的或它们支持什么操作。
asList.equals(listOf); // true i.f.f. same elements in same order
如果 列表中的元素数为 2 个或更少,则这些元素存储在专用(内部)类的字段中。例如,存储 2 个元素(部分源)的列表:List.of
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);
}
}
否则,它们将以类似于 的方式存储在数组中。Arrays.asList
基于字段 (size<2) 的实现在某些操作上执行得稍快。例如,可以在不获取数组长度的情况下返回常量,并且不需要迭代开销。List.of
size()
contains(E e)
通过 构建不可修改的列表也更快。将上述构造函数与 2 个引用赋值(甚至是任意数量的元素的赋值)进行比较List.of
Collections.unmodifiableList(Arrays.asList(...));
这将创建 2 个列表以及其他开销。在空间方面,您可以节省包装纸和一些便士。最终,等价物的节省更有说服力。UnmodifiableList
HashSet
结束时间:当您想要一个不会更改的列表以及当您想要一个可以更改的列表时(如上所示),请使用。List.of
Arrays.asList