Arrays.asList() 的返回值类型不是 java.util.ArrayList

起因:

写力扣的这道题 46. 全排列 时,看了灵茶山艾府的题解,发现他使用了一个 List.set() 方法,而该 List 是由 Arrays.asList() 转换的,于是去搜索了该方法的细节,总结如下:

Arrays.asList() 返回的是 java.util.List 的一个实现,该实现是 java.util.Arrays 内部定义的一个固定大小的、不支持结构性修改的 List 视图,其具体运行时类型为 java.util.Arrays$ArrayList

具体解释:

Arrays.asList() 可将数组转换为集合。源码:

@SafeVarargs
public static <T> List<T> asList(T... a) {
    return new ArrayList<>(a);
}

当使用该方法将数组转为 List 时,例如下述代码:

Integer[] nums = new Integer[10];
List<Integer> path = Arrays.asList(nums);

注意 asList 的返回值类型:

  • Arrays.asList(...) 在上述代码中接收的是一个数组参数
  • 它返回的是一个固定大小的 List 视图(fixed-size list view),底层直接引用传入的数组。该 List:
    • 类型是 java.util.List<T>,但具体实现类是 Arrays.ArrayList(其属于 java.util.Arrays 的内部类),如下图所示
    • 与原数组 nums 是双向绑定的(即修改操作,如 path.set(i, value) 会反映到 nums[i],反之亦然)
    • 不支持 add()remove() 等改变大小的操作(会抛出 UnsupportedOperationException

也就是说,asList 的返回值类型并不是我们集合框架中的那个 ArrayList,集合框架中的 ArrayListjava.util.ArrayList ,如果想将其转为集合框架中的 ArrayList,可以使用如下代码。

// 使用 ArrayList 的构造方法,传入原 List
Integer[] nums = new Integer[10];
List<Integer> fixedList = Arrays.asList(nums);
ArrayList<Integer> realArrayList = new ArrayList<>(fixedList);

这样:

  • realArrayListjava.util.ArrayList 类型;
  • 支持 add()remove() 等所有操作;
  • 内容是原数组的一个副本(后续修改 realArrayList 不会影响 nums 数组)。

参考:

[1] 常用工具类-Arrays

[2] 通义千问

[3] 【视频讲解】回溯不会写?套路在此!精确计算搜索树的节点个数!(Python/Java/C++/Go)

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐