Java Arrays.asList() 和 new ArrayList()对比

培训教学 潘老师 7个月前 (09-26) 156 ℃ (0) 扫码查看

学习如何使用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()方法创建的列表大小,但我们可以替换此列表中现有元素的值为新值,因为替换操作不会改变列表大小。
// 使用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())。我们还看到了它们之间的主要区别以及它们的内部工作方式,还提供了实际示例和用例。


版权声明:本站文章,如无说明,均为本站原创,转载请注明文章来源。如有侵权,请联系博主删除。
本文链接:https://www.panziye.com/teach/9295.html
喜欢 (0)
请潘老师喝杯Coffee吧!】
分享 (0)
用户头像
发表我的评论
取消评论
表情 贴图 签到 代码

Hi,您需要填写昵称和邮箱!

  • 昵称【必填】
  • 邮箱【必填】
  • 网址【可选】