List.of() 与 Arrays.asList()总结

List.of() 与 Arrays.asList() 是 Java 中用于创建列表的两种不同方法。虽然它们都用于创建包含一组元素的列表对象,但它们在实现、不可变性、适用场景和一些细节上存在重要差异。本文将详细分析这两种方法,讨论它们的异同点以及在什么情况下使用它们。

List.of()

List.of() 是 Java 9 引入的一个新方法,它属于 Java 集合框架的一部分,用于创建不可变(immutable)的列表对象。它接受可变数量的参数,返回一个包含这些参数的不可变列表。以下是 List.of() 的一些关键特点:

不可变性

List.of() 创建的列表是不可变的,这意味着一旦创建,就不能再添加、删除或修改其中的元素。这是通过使列表的方法抛出 UnsupportedOperationException 异常来实现的。不可变性在多线程环境下非常有用,因为它可以避免并发访问问题。

可变参数

List.of() 接受可变数量的参数,这意味着你可以将任意数量的元素传递给它,并且它会将这些元素包含在返回的列表中。这是一个非常方便的功能,因为你不需要创建数组或手动添加元素。

java 复制代码
List<String> colors = List.of("Red", "Green", "Blue");

长度固定

List.of() 创建的列表是固定长度的,即无法添加或删除元素。这意味着你不能使用 add()remove() 方法来修改列表。如果尝试这样做,会抛出 UnsupportedOperationException 异常。

不允许空元素

List.of() 不允许添加空元素(null)。如果尝试将空元素传递给它,会抛出 NullPointerException 异常。

线程安全

由于 List.of() 创建的列表是不可变的,它们在多线程环境中是线程安全的。这意味着多个线程可以同时读取这些列表而不会引发并发问题。

具有泛型支持

List.of() 支持泛型,因此你可以创建包含特定类型元素的列表。例如,List.of(1, 2, 3) 将创建一个 List<Integer>

返回类型

List.of() 返回的类型是 List 接口的一个实现,但它不是 ArrayList 或其他特定的列表类型。这是因为 List.of() 创建的列表是不可变的,没有可变长度或容量。

java 复制代码
List<String> colors = List.of("Red", "Green", "Blue");

Arrays.asList()

Arrays.asList() 是 Java 1.2 引入的方法,用于将数组转换为列表。它接受一个数组作为参数,返回一个包装数组的列表。以下是 Arrays.asList() 的一些关键特点:

基于数组

Arrays.asList() 是基于数组的,它将现有数组包装为一个列表。这意味着它的底层数据结构仍然是数组,因此它具有数组的一些特性,如固定长度。

java 复制代码
String[] colorsArray = {"Red", "Green", "Blue"};
List<String> colorsList = Arrays.asList(colorsArray);

可变性

Arrays.asList() 创建的列表是可变的,这意味着你可以使用 add()remove() 方法来修改列表中的元素。但需要注意的是,如果尝试调用 add()remove() 来更改数组大小,会引发 UnsupportedOperationException 异常,因为底层数组的大小是不可变的。

与底层数组的关联

Arrays.asList() 返回的列表与原始数组关联,这意味着对列表的更改也会反映在原始数组中。例如,如果你修改列表中的元素,原始数组也会被修改。

java 复制代码
String[] colorsArray = {"Red", "Green", "Blue"};
List<String> colorsList = Arrays.asList(colorsArray);

colorsList.set(0, "Yellow"); // 修改列表
System.out.println(Arrays.toString(colorsArray)); // 打印原始数组

允许空元素

List.of() 不同,Arrays.asList() 允许添加空元素(null)。这是因为它仅是将现有数组包装为列表,而不会在添加元素时执行额外的检查。

java 复制代码
List<String> listWithNull = Arrays.asList("Red", null, "Blue");

返回类型

Arrays.asList() 返回的类型是 List 接口的一个实现,但它的具体实现类是 ArrayList。这是因为它是基于数组的,但也提供了列表接口的功能。

java 复制代码
String[] colorsArray = {"Red", "Green", "Blue"};
List<String> colorsList = Arrays.asList(colorsArray);

List.of() 与 Arrays.asList() 的比较

现在,让我们比较一下这两种方法,分析它们的异同点以及在何种情况下使用哪个方法。

不可变性 vs 可变性

  • List.of() 创建的列表是不可变的,而 Arrays.asList() 创建的列表是可变的。如果你需要一个不可变的列表,以避免数据被修改,可以使用 List.of()
  • 如果你需要一个可变的列表,以便添加、删除或修改元素,可以使用 Arrays.asList()

可变参数 vs 数组

  • List.of() 接受可变数量的参数,不需要手动创建数组。这使得创建列表更加方便。
  • Arrays.asList() 需要传递一个现有的数组作为参数。如果你已经有一个数组并希望将其转换为列表,可以使用

Arrays.asList()

固定长度 vs 关联数组

  • List.of() 创建的列表是固定长度的,无法添加或删除元素。这可以帮助确保数据的不可变性。
  • Arrays.asList() 创建的列表可以添加或删除元素,但底层数组的大小是不可变的。它与底层数组关联,因此对列表的更改会影响原始数组。

允许空元素 vs 不允许空元素

  • List.of() 不允许添加空元素,如果传递 null,会抛出异常。
  • Arrays.asList() 允许添加空元素,不会执行额外的检查。

线程安全性

  • 由于 List.of() 创建的列表是不可变的,它们在多线程环境中是线程安全的。
  • Arrays.asList() 创建的列表是可变的,因此在多线程环境中需要进行同步处理,以避免并发问题。

返回类型

  • List.of() 返回的类型是 List 接口的一个实现,但它不是 ArrayList 或其他特定的列表类型。这是因为 List.of() 创建的列表是不可变的。
  • Arrays.asList() 返回的类型也是 List 接口的一个实现,但它的具体实现类是 ArrayList。这是因为它是基于数组的,同时也提供了列表接口的功能。

使用场景

现在让我们讨论在什么情况下使用 List.of()Arrays.asList()

适合使用 List.of() 的情况

  • 当你需要创建一个不可变的、固定长度的列表,并且不希望在后续的操作中修改列表时,可以使用 List.of()
  • 当你有一组元素,并且希望快速创建一个列表,而不需要显式地创建数组时,可以使用 List.of()
  • 在多线程环境下,如果你需要一个线程安全的不可变列表,List.of() 是一个很好的选择。
java 复制代码
List<String> colors = List.of("Red", "Green", "Blue");

适合使用 Arrays.asList() 的情况

  • 当你已经有一个数组,并且希望将其转换为列表时,可以使用 Arrays.asList()
  • 当你需要一个可变的列表,以便在后续操作中添加、删除或修改元素时,可以使用 Arrays.asList()
  • 当你需要一个具有 ArrayList 功能的列表,同时又能使用 List 接口时,Arrays.asList() 是一个合适的选择。
java 复制代码
String[] colorsArray = {"Red", "Green", "Blue"};
List<String> colorsList = Arrays.asList(colorsArray);

总结

List.of()Arrays.asList() 是 Java 中用于创建列表的两种不同方法,它们在不可变性、可变性、允许空元素、关联数组、返回类型等方面存在重要差异。你可以根据你的需求选择适当的方法。

  • 使用 List.of() 创建的列表是不可变的,适用于需要不可变性和线程安全性的情况。
  • 使用 Arrays.asList() 创建的列表是可变的,适用于需要在后续操作中修改列表的情况,同时它与底层数组关联。
  • 要注意 List.of() 不允许空元素,而 Arrays.asList() 允许。

最终,选择哪种方法取决于你的具体需求和代码设计。不同的场景可能需要不同的方法来满足需求,因此理解它们的特点和差异对于做出明智的决策至关重要。无论你选择哪种方法,都要确保根据需要正确使用它们,以获得最佳的性能和可维护性。

相关推荐
测开小菜鸟1 小时前
使用python向钉钉群聊发送消息
java·python·钉钉
P.H. Infinity2 小时前
【RabbitMQ】04-发送者可靠性
java·rabbitmq·java-rabbitmq
生命几十年3万天2 小时前
java的threadlocal为何内存泄漏
java
caridle3 小时前
教程:使用 InterBase Express 访问数据库(五):TIBTransaction
java·数据库·express
^velpro^3 小时前
数据库连接池的创建
java·开发语言·数据库
苹果醋33 小时前
Java8->Java19的初步探索
java·运维·spring boot·mysql·nginx
秋の花3 小时前
【JAVA基础】Java集合基础
java·开发语言·windows
小松学前端3 小时前
第六章 7.0 LinkList
java·开发语言·网络
Wx-bishekaifayuan3 小时前
django电商易购系统-计算机设计毕业源码61059
java·spring boot·spring·spring cloud·django·sqlite·guava
customer083 小时前
【开源免费】基于SpringBoot+Vue.JS周边产品销售网站(JAVA毕业设计)
java·vue.js·spring boot·后端·spring cloud·java-ee·开源