Java 实例 – 数组合并(长文讲解)

Java 实例 – 数组合并:从基础到实战的完整指南

在日常开发中,我们常常需要将两个或多个数组中的数据整合成一个统一的集合。这在处理用户数据、日志信息、配置参数等场景中非常常见。而 Java 作为一门广泛使用的编程语言,提供了多种方式来实现“数组合并”这一核心操作。本文将带你从零开始,通过真实代码示例,深入理解 Java 实例 – 数组合并 的多种实现方法,适合初学者快速上手,也适合中级开发者查漏补缺。


为什么要进行数组合并?

想象一下你正在开发一个电商平台的订单系统。前端分别传来了“已发货订单”和“待发货订单”两个数组。为了统一展示,你必须把它们合并成一个完整的订单列表。这种“合并”操作,就是典型的数组合并场景。

在 Java 中,数组是固定长度的数据结构,无法动态扩容,因此直接合并两个数组不能像集合那样直接调用 addAll()。这就需要我们掌握一些技巧。接下来,我们一步步来探索。


创建数组与初始化

在进行任何合并操作之前,首先要学会如何创建和初始化数组。这是所有操作的基础。

// 创建一个整型数组,长度为 3
int[] arr1 = new int[3];

// 通过数组字面量方式初始化
int[] arr2 = {10, 20, 30};

// 创建字符串数组并赋值
String[] arr3 = {"苹果", "香蕉", "橙子"};

💡 小贴士:数组一旦创建,长度就固定了。比如 new int[3] 就只能存 3 个元素,不能自动扩展。这也是为什么合并时需要新建一个更大的数组。


方法一:使用 System.arraycopy() 实现高效合并

System.arraycopy() 是 Java 提供的一个本地方法,用于高效复制数组内容。它比手动循环快得多,尤其适合处理大量数据。

public static int[] mergeArrays(int[] arr1, int[] arr2) {
    // 1. 计算合并后数组的总长度
    int totalLength = arr1.length + arr2.length;
    
    // 2. 创建一个新数组,用于存放合并结果
    int[] result = new int[totalLength];
    
    // 3. 使用 System.arraycopy 将第一个数组复制到结果数组中
    // 参数说明:
    // - arr1: 源数组
    // - 0: 从源数组的第 0 个位置开始复制
    // - result: 目标数组
    // - 0: 复制到目标数组的第 0 个位置
    // - arr1.length: 要复制的元素个数
    System.arraycopy(arr1, 0, result, 0, arr1.length);
    
    // 4. 将第二个数组复制到结果数组的后面位置
    // 从 result 的 arr1.length 位置开始,复制 arr2 的所有元素
    System.arraycopy(arr2, 0, result, arr1.length, arr2.length);
    
    // 5. 返回合并后的结果
    return result;
}

优点:性能极高,底层是 C 语言实现,适合大数据量合并。
注意:只能用于同类型数组,且目标数组必须提前分配足够空间。


方法二:使用循环逐个添加元素

这是最直观、最容易理解的方式,适合初学者掌握逻辑。

public static String[] mergeStringArrays(String[] arr1, String[] arr2) {
    // 1. 计算合并后数组的长度
    int totalLength = arr1.length + arr2.length;
    
    // 2. 创建新数组
    String[] result = new String[totalLength];
    
    // 3. 使用 for 循环将第一个数组的元素依次放入结果数组
    for (int i = 0; i < arr1.length; i++) {
        result[i] = arr1[i]; // 把 arr1 的第 i 个元素放到 result 的第 i 个位置
    }
    
    // 4. 将第二个数组的元素从 arr1.length 位置开始放入
    for (int i = 0; i < arr2.length; i++) {
        result[arr1.length + i] = arr2[i]; // 偏移量为 arr1.length
    }
    
    return result;
}

💬 形象比喻:你可以把数组想象成一排空抽屉。第一个循环是把“A 箱子”的东西放进前几个抽屉,第二个循环是把“B 箱子”的东西放进后面的抽屉。最终,所有物品都被整齐地合并到了一个大抽屉里。


方法三:借助 List 集合,再转回数组

如果你更熟悉集合操作,可以先将数组转为 List,合并后再转回数组。

import java.util.Arrays;
import java.util.List;
import java.util.ArrayList;

public static Integer[] mergeWithList(Integer[] arr1, Integer[] arr2) {
    // 1. 将数组转为 List
    List<Integer> list1 = Arrays.asList(arr1);
    List<Integer> list2 = Arrays.asList(arr2);
    
    // 2. 创建一个新的 ArrayList,用于合并
    List<Integer> mergedList = new ArrayList<>();
    
    // 3. 添加第一个列表的所有元素
    mergedList.addAll(list1);
    
    // 4. 添加第二个列表的所有元素
    mergedList.addAll(list2);
    
    // 5. 将 List 转回数组
    // toArray() 方法需要传入一个泛型数组,用于指定返回类型
    return mergedList.toArray(new Integer[0]);
}

优势:代码简洁,可读性强,支持动态扩容。
注意Arrays.asList() 返回的列表是固定大小的,不能直接调用 add(),所以必须用 ArrayList 包装。


实际应用场景:合并用户订单数据

让我们看一个更贴近实际的案例。假设你有两个订单数组,分别来自不同接口:

// 模拟数据:已发货订单
String[] shippedOrders = {"订单001", "订单003", "订单005"};
// 模拟数据:待发货订单
String[] pendingOrders = {"订单002", "订单004", "订单006"};

// 调用合并方法
String[] allOrders = mergeStringArrays(shippedOrders, pendingOrders);

// 打印结果
System.out.println("所有订单列表:");
for (String order : allOrders) {
    System.out.println(order);
}

输出结果:

所有订单列表:
订单001
订单003
订单005
订单002
订单004
订单006

🔍 观察:虽然合并了,但顺序是按“先发货后待发”排列的。如果需要按订单号排序,可以额外调用 Arrays.sort()


性能对比与选择建议

方法 适用场景 性能 可读性 备注
System.arraycopy() 大数据量、性能敏感 ⭐⭐⭐⭐⭐ ⭐⭐⭐ 最快,但需手动管理长度
循环合并 初学者、逻辑清晰 ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ 易懂,适合教学
List 转换 需要动态操作、复杂逻辑 ⭐⭐⭐ ⭐⭐⭐⭐ 代码简洁,但有额外开销

推荐

  • 小数据量或学习阶段:用循环法,理解逻辑。
  • 高性能要求:优先使用 System.arraycopy()
  • 复杂业务逻辑:用 List 转换,方便扩展。

常见错误与注意事项

  1. 数组长度错误:忘记计算总长度,导致 ArrayIndexOutOfBoundsException
  2. 类型不匹配:尝试合并 int[]String[],编译不通过。
  3. 未初始化新数组:直接往 null 数组赋值,会抛出 NullPointerException
  4. 忽略空数组:如果其中一个数组为 null,需提前判断,避免 NullPointerException
// 安全的合并方法示例
public static int[] safeMerge(int[] arr1, int[] arr2) {
    if (arr1 == null) arr1 = new int[0];
    if (arr2 == null) arr2 = new int[0];
    
    int totalLength = arr1.length + arr2.length;
    int[] result = new int[totalLength];
    
    System.arraycopy(arr1, 0, result, 0, arr1.length);
    System.arraycopy(arr2, 0, result, arr1.length, arr2.length);
    
    return result;
}

总结:掌握 Java 实例 – 数组合并的关键

数组合并是 Java 开发中的高频操作。通过本文的学习,你已经掌握了三种主流实现方式:System.arraycopy() 的高性能合并、循环逐个添加的直观逻辑,以及借助 List 的灵活处理。每种方法都有其适用场景。

记住:没有“最好”的方法,只有“最合适”的方法。根据数据量、可读性需求、性能要求来选择。在实际项目中,多写、多试、多调试,才能真正掌握这些基础但至关重要的技能。

无论是初学者还是中级开发者,只要理解了数组的“长度固定”本质,就能从容应对各种合并场景。希望这篇 Java 实例 – 数组合并 的实战指南,能成为你编程路上的坚实脚手架。