杰瑞科技汇

Java数组如何转ArrayList?

方法 代码示例 优点 缺点 适用场景
使用 Arrays.asList() List<String> list = Arrays.asList(arr); 最简单、最直接,性能高 返回的是固定长度ArrayList,不能增删 当你只需要一个 List读取数组元素时
使用 Java 8 Stream List<String> list = Arrays.stream(arr).collect(Collectors.toList()); 灵活,可链式操作,返回真正可变ArrayList 代码稍长,对于简单转换略显繁琐 需要对数组元素进行过滤、映射等操作,或需要一个可变列表
使用 Collections.addAll() List<String> list = new ArrayList<>(); Collections.addAll(list, arr); 返回真正可变ArrayList,性能也很好 需要先创建一个空的 ArrayList 对象 当你明确需要一个可变列表,并且不想使用 Stream 时

使用 Arrays.asList() (最常用)

这是最直接、最简单的方法,但它有一个非常重要的“陷阱”。

代码示例

import java.util.Arrays;
import java.util.List;
public class ArrayToListExample {
    public static void main(String[] args) {
        // 1. 定义一个 String 数组
        String[] stringArray = {"Apple", "Banana", "Orange"};
        // 2. 使用 Arrays.asList() 将数组转换为 List
        // 注意:这里得到的 List 是 java.util.Arrays.ArrayList,它是一个内部类
        List<String> fruitList = Arrays.asList(stringArray);
        System.out.println("转换后的 List: " + fruitList);
        System.out.println("List 的第一个元素: " + fruitList.get(0));
        // --- 重要的警告 ---
        System.out.println("\n--- 尝试修改 List ---");
        // 修改 List 中的元素(可以修改)
        fruitList.set(0, "Grape");
        System.out.println("修改 List 后的数组: " + Arrays.toString(stringArray)); // 数组也被修改了!
        System.out.println("修改 List 后的 List: " + fruitList);
        // 尝试向 List 中添加新元素(会抛出异常)
        try {
            fruitList.add("Mango");
            System.out.println("添加元素成功: " + fruitList);
        } catch (UnsupportedOperationException e) {
            System.out.println("错误: 不能向由 Arrays.asList() 创建的 List 中添加元素!");
        }
        // 尝试从 List 中删除元素(同样会抛出异常)
        try {
            fruitList.remove(0);
            System.out.println("删除元素成功: " + fruitList);
        } catch (UnsupportedOperationException e) {
            System.out.println("错误: 不能从由 Arrays.asList() 创建的 List 中删除元素!");
        }
    }
}

关键点解析

  1. 返回类型Arrays.asList() 返回的 List 并不是我们平时常用的 java.util.ArrayList,它是一个固定长度(fixed-size)的列表,是 Arrays 类的一个内部类。
  2. 视图而非副本:这个 List原始数组的视图,这意味着你对 List 的任何修改(set())都会直接反映到原始数组上,反之亦然。
  3. 不可增删:由于它是固定长度的,所以你不能使用 add()remove() 方法来改变其大小,否则会抛出 UnsupportedOperationException

适用场景

当你只需要遍历数组,或者基于数组创建一个只读的 List 视图时,这个方法非常高效。


使用 Java 8 Stream API (最灵活)

如果你需要一个真正可以修改大小的 ArrayList,或者想在转换过程中进行一些操作,Stream API 是最佳选择。

代码示例

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class StreamExample {
    public static void main(String[] args) {
        // 1. 定义一个 Integer 数组
        Integer[] intArray = {1, 2, 3, 4, 5};
        // 2. 使用 Stream API 转换
        List<Integer> numberList = Arrays.stream(intArray) // 1. 创建一个流
                                        .collect(Collectors.toList()); // 2. 将流收集到新的 List 中
        System.out.println("转换后的 List: " + numberList);
        // --- 优势:可以轻松进行链式操作 ---
        List<Integer> evenNumbers = Arrays.stream(intArray)
                                          .filter(n -> n % 2 == 0) // 过滤出偶数
                                          .collect(Collectors.toList());
        System.out.println("过滤后的偶数 List: " + evenNumbers);
        // --- 优势:返回的是真正的可变 ArrayList ---
        numberList.add(6); // 可以添加
        numberList.remove(0); // 可以删除
        System.out.println("修改后的 List: " + numberList);
    }
}

关键点解析

  1. Arrays.stream(arr):将数组转换为 Stream
  2. .collect(Collectors.toList()):这是流的终端操作,它将流中的元素收集到一个新的 List 中,这个 List 默认就是 java.util.ArrayList,是完全可变的。
  3. 灵活性:在 collect 之前,你可以进行各种中间操作,如 filter()(过滤)、map()(转换)、sorted()(排序)等。

适用场景

当你需要一个可变ArrayList,或者想在转换数组的同时对元素进行处理时,这是现代 Java 中最推荐的方法。


使用 Collections.addAll() (传统方法)

这是一种比较传统但有效的方法,同样可以得到一个可变的 ArrayList

代码示例

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class CollectionsAddAllExample {
    public static void main(String[] args) {
        // 1. 定义一个 String 数组
        String[] stringArray = {"Cat", "Dog", "Bird"};
        // 2. 创建一个新的空的 ArrayList
        List<String> animalList = new ArrayList<>();
        // 3. 使用 Collections.addAll() 将数组所有元素添加到 List 中
        Collections.addAll(animalList, stringArray);
        System.out.println("转换后的 List: " + animalList);
        // --- 这是一个真正的可变 ArrayList ---
        animalList.add("Fish");
        animalList.remove("Cat");
        System.out.println("修改后的 List: " + animalList);
    }
}

关键点解析

  1. 需要预先创建 List:你必须先创建一个空的 ArrayList 实例。
  2. 性能好Collections.addAll() 方法在内部使用高效的 System.arraycopy,性能很高。
  3. 返回可变列表:最终得到的 animalList 是一个标准的、可修改的 ArrayList

适用场景

在不使用 Stream API 的旧代码中,或者当你明确想分步骤(先创建列表,再填充内容)时,这是一个很好的选择。


总结与最佳实践

特性 Arrays.asList() Stream API (Collectors.toList()) Collections.addAll()
是否可变 (固定大小) (标准 ArrayList) (标准 ArrayList)
代码简洁性 最高 中等 中等
灵活性 低 (仅视图) 最高 (可链式操作) 低 (仅添加)
性能 最高 (直接包装) 较好 (有流操作开销) (底层是 arraycopy)

如何选择?

  1. 只需要读取数据:如果你的唯一目的就是遍历数组或者把它当作一个只读的集合传递给方法,使用 Arrays.asList(),它最快、最简单。

  2. 需要一个可修改的列表:如果你需要向结果列表中添加或删除元素,请避免使用 Arrays.asList()

    • 推荐使用 Stream API: Arrays.stream(arr).collect(Collectors.toList()),这是现代 Java 的标准做法,不仅功能强大,而且代码意图清晰。
    • 备选方案: 如果项目不能使用 Java 8+,或者你不喜欢 Stream 的写法,可以使用 Collections.addAll()
  3. 转换时需要处理数据:如果你想在转换数组的同时过滤、排序或转换元素,Stream API 是唯一的选择

    int[] nums = {1, 2, 3, 4, 5};
    List<Integer> squaredEvens = Arrays.stream(nums)
                                      .filter(n -> n % 2 == 0)
                                      .map(n -> n * n)
                                      .boxed() // int -> Integer
                                      .collect(Collectors.toList());
    // 结果是 [4, 16]
分享:
扫描分享到社交APP
上一篇
下一篇