章
目
录
学习如何使用Arrays.asList(array)和new ArrayList(Arrays.asList(array))从数组创建List。使用这些方法创建的List在多种方面存在差异。让我们探讨一些它们之间的主要区别。
1.介绍
Arrays是java.util包中的一个实用类,自Java版本1.2以来一直存在。它提供了各种实用方法来处理对象数组。Arrays.asList()是从给定数组创建List的方法之一。它不会创建一个独立的List对象,而是返回一个List视图,即创建的List是固定大小的,无法添加或删除其中的元素。
public static List asList(Object[] arr)
ArrayList类位于java.util包中,它继承了AbstractList类并实现了List接口,自Java版本1.2以来一直存在。我们可以使用该类的构造函数之一从现有数组创建一个List。它创建一个独立的List实例,不是固定大小的,可以根据需要进行更改。
ArrayList list = new ArrayList(Arrays.asList(array))
2.Arrays.asList(array) 和 new ArrayList(Arrays.asList(array))区别
2.1. 返回的List
Arrays.asList(array) 在底层数组上创建一个List包装器,并返回一个类型为java.util.Arrays.ArrayList的List,这与java.util.ArrayList不同。它为数组提供了一个列表视图,实际上不会将任何元素复制到创建的List中。
// 定义字符串数组
String[] stringArray = {"a", "b", "c"};
// 使用Arrays.asList()方法创建列表
List<String> listofStrings = Arrays.asList(stringArray);
// 打印类名称
System.out.println(listofStrings.getClass().getCanonicalName()); // java.util.Arrays.ArrayList
使用new ArrayList(Arrays.asList(array)) 创建的List的类型是java.util.ArrayList类。我们将一个列表包装器传递给ArrayList构造函数,构造函数会从中实际复制所有元素并创建一个新的独立的ArrayList对象。
// 定义字符串数组
String[] stringArray = {"a", "b", "c"};
//使用new ArrayList()创建列表
List<String> listofStrings = new ArrayList<>(Arrays.asList(stringArray));
// 打印类名称
System.out.println(listofStrings.getClass().getCanonicalName()); // java.util.ArrayList
2.2. 添加和移除元素
Arrays.asList(array) 创建一个固定大小的List,因为数组的长度是固定的,而这种方法只是在底层数组上创建一个列表包装器,所以创建的List也遵循固定大小的规则。
我们不能向这个列表中添加或删除元素。如果我们尝试执行任何会改变列表大小的操作,那么列表将抛出UnsupportedOperationException异常。
// 使用Arrays.asList()方法创建列表
List<String> listofStrings = Arrays.asList(stringArray);
// 打印列表
System.out.println(listofStrings); // [a, b, c]
// 将元素添加到列表
listofStrings.add(“d”); // Raises UnsupportedOperationException
// 替换列表中的元素
listofStrings.set(0, “z”);
// 打印列表
System.out.println(listofStrings); // [z, b, c]
ArrayList(Arrays.asList(array)) 创建一个独立的List,它不是固定大小的,因此我们可以添加、移除和修改这个列表的元素。
// 使用new ArrayList()创建列表
List<String> listofStrings = new ArrayList<>(Arrays.asList(stringArray));
// 打印列表
System.out.println(listofStrings); // [a, b, c]
// 将元素添加到列表
listofStrings.add(“d”);
// 打印列表
System.out.println(listofStrings); // [a, b, c, d]
// 替换列表中的元素
listofStrings.set(0, “z”);
// Printing list
System.out.println(listofStrings); // [z, b, c, d]
2.3.底层数组和列表的内部引用
当使用 Arrays.asList(array) 创建一个列表时,列表和底层数组都指向堆内存区域中的同一对象。我们不会在内存中为输入数组和创建的列表拥有两个独立的对象。
使用 new ArrayList(Arrays.asList(array))
,我们最终在堆内存区域中会有两个独立的对象,一个是输入数组,另一个是创建的列表。
2.4. 改变列表项时对底层数组的影响
如上所述,对于 Arrays.asList(array) 的情况,输入数组和创建的列表都指向内存中的同一对象。因此,通过列表引用,如果我们进行任何更改,相同的更改将反映在底层数组中,反之亦然。
// 使用Arrays.asList()方法创建列表
List<String> listofStrings = Arrays.asList(stringArray);
// 打印基础数组和列表
System.out.println(Arrays.toString(stringArray)); // [a, b, c]
System.out.println(listofStrings); // [a, b, c]
// 替换列表中的元素
listsofStrings.set(0, “z”);
// 再次打印基础数组和列表
System.out.println(Arrays.toString(stringArray)); // [z, b, c]
System.out.println(listofStrings); // [z, b, c]
对于 new ArrayList(Arrays.asList(array))
,我们有两个独立的对象,一个用于底层数组,另一个用于创建的列表;修改其中一个不会以任何方式影响另一个。
// new ArrayList()创建列表
List<String> listofStrings = new ArrayList<>(Arrays.asList(stringArray));
// 打印基础数组和列表
System.out.println(Arrays.toString(stringArray)); // [a, b, c]
System.out.println(listofStrings); // [a, b, c]
// 替换列表中的元素
listsofStrings.set(0, “z”);
// 再次打印基础数组和列表
System.out.println(Arrays.toString(stringArray)); // [a, b, c]
System.out.println(listofStrings); // [z, b, c]
3.何时使用?
如果我们的需求是从数组创建一个不可修改的列表,即我们需要一个列表,我们可以经常从中读取数据,并且不需要在该列表上执行任何插入/删除操作,那么我们可以使用 Arrays.asList()
方法。
另一方面,如果我们的需求是从数组创建一个独立的可修改列表,从中可以读取数据,同时也可以通过添加/删除元素来修改列表,那么我们可以使用 new ArrayList(Arrays.asList())
。
从性能的角度来看,Arrays.asList()
的性能优于 new ArrayList(Arrays.asList())
。后者需要O(n)的时间复杂度来从数组创建一个列表,因为它在内部使用 System.arrayCopy()
方法将元素从数组复制到列表中。
而 Arrays.asList()
在此情况下执行操作的时间复杂度为O(1),因为不需要从输入数组复制数据到列表中。
4.将 Arrays.asList() 转换为 ArrayList
让我们看看如何将使用 Arrays.asList()
获得的列表转换为一个新的 ArrayList()
的各种方法。
4.1. 使用 ArrayList 构造函数
我们可以使用 ArrayList
类的构造函数 new ArrayList()
来获得一个独立的列表对象。
ArrayList<String> list = new ArrayList<>(Arrays.asList(stringArray));
4.2. 使用传统的 for-each 循环
我们可以使用 for-each 循环来迭代通过 Arrays.asList()
生成的列表,并将每个元素添加到 ArrayList
中。
//使用Arrays.asList()方法创建列表
List<String> listofStrings = Arrays.asList(stringArray);
// 创建 ArrayList
ArrayList<String> list = new ArrayList<>();
//遍历 list
for(String str : listofStrings){
// Adding str in ArrayList
list.add(str);
}
// 打印ArrayList引用
System.out.println(list); // [a, b, c]
// 修改创建的ArrayList
list.add(“d”);
list.add(“e”);
// 再次打印ArrayList引用
System.out.println(list); // [a, b, c, d, e]
5.结论
我们已经学会了通过两种方式将数组转换为列表——使用 Arrays.asList()
和 new ArrayList(Arrays.asList())
。我们还看到了它们之间的主要区别以及它们的内部工作方式,还提供了实际示例和用例。