杰瑞科技汇

ArrayList与数组如何高效转换?

ArrayList 转换为数组

这是将动态集合转为固定大小数组的操作,Java 提供了两种主要方法:toArray()toArray(T[] a)

ArrayList与数组如何高效转换?-图1
(图片来源网络,侵删)

使用 toArray() 无参方法

这种方法最简单,但有一个重要的限制

  • 功能:创建一个 Object 类型的数组,并将 ArrayList 中的所有元素复制到这个新数组中。
  • 语法Object[] array = list.toArray();
  • 缺点:返回的是 Object[] 数组,如果你希望得到特定类型(如 String[]Integer[])的数组,需要进行强制类型转换,这可能会在运行时抛出 ClassCastException

示例代码:

import java.util.ArrayList;
public class ArrayListToArrayExample1 {
    public static void main(String[] args) {
        // 1. 创建一个 ArrayList
        ArrayList<String> names = new ArrayList<>();
        names.add("Alice");
        names.add("Bob");
        names.add("Charlie");
        // 2. 使用无参的 toArray() 方法
        // 返回的是 Object[] 类型
        Object[] objectArray = names.toArray();
        // 3. 打印数组内容
        System.out.println("使用 toArray() 转换后的数组:");
        for (Object obj : objectArray) {
            System.out.println(obj);
        }
        // 如果你想将其转为 String[],需要强制转换,有风险
        // String[] stringArray = (String[]) objectArray; // 这行代码会抛出 ClassCastException
    }
}

使用 toArray(T[] a) 有参方法 (推荐)

这是最常用、最安全、最灵活的方法。

  • 功能:创建一个与你传入的数组类型相同的数组,并将 ArrayList 的元素复制进去。
  • 语法T[] array = list.toArray(new T[0]);
    • TArrayList 中元素的类型(String, Integer)。
    • 传入的参数 new T[0] 是一个空的、指定类型的数组,这只是一个“模板”,JVM 会根据这个模板创建一个大小合适的数组来存放所有元素。
  • 优点
    1. 类型安全:返回的数组类型与 ArrayList 的泛型类型完全匹配,无需强制转换,避免了 ClassCastException
    2. 效率高:避免了创建 Object[] 再进行转换的开销。

示例代码:

ArrayList与数组如何高效转换?-图2
(图片来源网络,侵删)
import java.util.ArrayList;
public class ArrayListToArrayExample2 {
    public static void main(String[] args) {
        // 1. 创建一个 ArrayList
        ArrayList<String> names = new ArrayList<>();
        names.add("Alice");
        names.add("Bob");
        names.add("Charlie");
        // 2. 使用有参的 toArray(T[] a) 方法
        // 传入一个空的 String[] 作为模板
        String[] stringArray = names.toArray(new String[0]);
        // 3. 打印数组内容
        System.out.println("使用 toArray(new String[0]) 转换后的数组:");
        for (String name : stringArray) {
            System.out.println(name);
        }
    }
}

数组转换为 ArrayList

这是将固定大小数组转为动态集合的操作,同样,Java 提供了两种方法,但强烈推荐其中一种

使用 Arrays.asList() (推荐)

这是最直接、最推荐的方法。

  • 功能:将一个数组转换为一个固定大小的 List
  • 语法List<T> list = Arrays.asList(array);
  • 重要特性与注意事项
    1. 返回的是 Arrays 的内部类Arrays.asList() 返回的并不是我们常用的 java.util.ArrayList,而是一个名为 ArrayList静态内部类java.util.Arrays.ArrayList)。
    2. 大小固定:这个 List固定大小的,你不能向其中添加或删除元素,否则会抛出 UnsupportedOperationException
    3. 底层是原数组:这个 List 与原始数组是 backed by the original array,这意味着对 List 的任何修改(如 set())都会直接反映到原始数组上,反之亦然。

示例代码:

import java.util.Arrays;
import java.util.List;
public class ArrayToArrayListExample1 {
    public static void main(String[] args) {
        // 1. 创建一个数组
        String[] stringArray = {"Apple", "Banana", "Orange"};
        // 2. 使用 Arrays.asList() 转换
        List<String> fruitList = Arrays.asList(stringArray);
        System.out.println("转换后的 List 内容: " + fruitList);
        System.out.println("List 的 size: " + fruitList.size());
        // 3. 修改 List,会影响原数组
        fruitList.set(0, "Mango");
        System.out.println("修改 List 后的 List 内容: " + fruitList);
        System.out.println("修改 List 后的原数组内容: " + Arrays.toString(stringArray)); // 原数组也被修改了
        // 4. 尝试添加元素会抛出异常
        try {
            fruitList.add("Grape"); // 抛出 UnsupportedOperationException
        } catch (UnsupportedOperationException e) {
            System.out.println("\n尝试添加元素失败: " + e);
        }
    }
}

创建一个新的 ArrayList 并添加所有元素

如果你需要一个真正可变java.util.ArrayList,应该使用这种方法。

ArrayList与数组如何高效转换?-图3
(图片来源网络,侵删)
  • 功能:创建一个新的 ArrayList,并将数组中的所有元素逐个添加进去。
  • 语法
    List<T> list = new ArrayList<>(Arrays.asList(array));
    // 或者
    List<T> list = new ArrayList<>();
    Collections.addAll(list, array);
  • 优点
    1. 真正的可变 ArrayList:你可以自由地添加、删除、修改这个 List
    2. 与原数组解耦:对这个 List 的修改不会影响原始数组。

示例代码:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class ArrayToArrayListExample2 {
    public static void main(String[] args) {
        // 1. 创建一个数组
        String[] stringArray = {"Apple", "Banana", "Orange"};
        // 2. 方法 A: 使用 ArrayList 的构造函数
        List<String> fruitList1 = new ArrayList<>(Arrays.asList(stringArray));
        // 3. 方法 B: 使用 Collections.addAll()
        List<String> fruitList2 = new ArrayList<>();
        Collections.addAll(fruitList2, stringArray);
        // 4. 现在可以自由地修改这个 List
        fruitList1.add("Grape");
        fruitList1.remove("Banana");
        System.out.println("使用构造函数转换后的 List: " + fruitList1);
        System.out.println("原数组内容未受影响: " + Arrays.toString(stringArray));
    }
}

总结与最佳实践

转换方向 方法 代码示例 优点 缺点/注意事项 推荐度
ArrayList → 数组 无参 toArray() Object[] arr = list.toArray(); 简单 返回 Object[],类型不安全,需强制转换。 ⭐⭐
有参 toArray(T[] a) String[] arr = list.toArray(new String[0]); 类型安全,高效 ⭐⭐⭐⭐⭐ (强烈推荐)
数组 → ArrayList Arrays.asList() List<String> list = Arrays.asList(arr); 简洁,高效 返回的是固定大小List,不是 java.util.ArrayList,修改会影响原数组。 ⭐⭐⭐⭐ (如果只需要遍历)
构造新 ArrayList List<String> list = new ArrayList<>(Arrays.asList(arr)); 返回真正的可变 ArrayList,与原数组解耦。 需要创建新对象,内存开销稍大。 ⭐⭐⭐⭐⭐ (如果需要修改 List)

核心要点:

  1. ArrayList数组:总是使用 list.toArray(new T[0]) 来保证类型安全和效率。
  2. 数组ArrayList
    • 如果你只是想遍历数组,或者需要一个基于数组的固定大小视图,使用 Arrays.asList()
    • 如果你需要一个可以随意增删改查的标准 List,请使用 `new ArrayList<>(
分享:
扫描分享到社交APP
上一篇
下一篇