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 转换,方便扩展。
常见错误与注意事项
- 数组长度错误:忘记计算总长度,导致
ArrayIndexOutOfBoundsException。 - 类型不匹配:尝试合并
int[]和String[],编译不通过。 - 未初始化新数组:直接往
null数组赋值,会抛出NullPointerException。 - 忽略空数组:如果其中一个数组为
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 实例 – 数组合并 的实战指南,能成为你编程路上的坚实脚手架。