如何在 Java 中合并两个数组?

12 Feb 2025 | 7 分钟阅读

在 Java 中合并两个数组是一项基本操作,在各种应用程序中经常需要。根据具体需求和问题约束,可以通过多种方式完成。

在 Java 中合并两个数组类似于将两个数组连接或组合到一个数组对象中。我们必须合并两个数组,以便数组元素在新的合并数组中保持其原始顺序。第一个数组的元素在新合并的数组中位于第二个数组的元素之前。

例如

用例

在 Java 中合并两个数组是在各种场景中常见的任务,包括:

数据处理:处理存储在多个数组中的数据集时,合并它们可以简化数据处理和分析。例如,合并学生姓名和相应成绩的数组有助于计算平均值或按成绩排序。

用户输入:在用户可以分批或分段输入数据的应用程序中,合并数组可以方便地将多个输入数组合并到一个数据集中,以进行进一步处理或存储。

数据库操作:从数据库检索数据时,结果可能存储在表示不同列或属性的独立数组中。合并这些数组可以整合数据以供显示或操作。

排序和搜索:合并数组通常是排序或搜索算法的前提。在应用这些操作之前,必须将较小的数组合并到较大的数组中,以确保在整个数据集中进行正确的排序或搜索。

资源管理:在资源受限的环境中,合并数组可以通过最大限度地减少独立数组的数量来节省内存,从而实现更有效的资源利用。

合并两个数组的方法

以下是合并两个数组的方法:

  • Java System.arraycopy() 方法
  • 不使用 arraycopy() 方法
  • Java Collections
  • Java Stream API

Java System.arraycopy() 方法

Java 中的 System.arraycopy() 方法是一种强大而高效的将元素从一个数组复制到另一个数组的方法。它用于执行数组元素的浅拷贝。它可以用于将元素从一个数组复制到另一个数组,复制子数组,或在数组内移动元素。复制的元素数量等于 length 参数。

语法

参数

  • source:源数组。
  • source_position:源数组中的起始点。
  • destination:目标数组。
  • destination_position:目标数组中的起始位置。
  • length:要复制的数组元素的数量

如果源数组或目标数组为 null,它将抛出 NullPointerException。如果发生以下情况,它还将抛出 ArrayIndexOutOfBoundsException

  • source_positiondestination_position 或 length 为负。
  • source_position+length 大于源数组的长度,或 destination_position+length 大于目标数组的长度。

arraycopy() 方法示例

在以下示例中,我们创建了两个整数数组 firstArraysecondArray。为了合并两个数组,我们计算它们的长度并分别存储在 fal 和 sal 变量中。之后,我们创建一个新的整数数组 result,它存储两个数组长度的总和。现在,使用 arraycopy() 函数将两个数组的每个元素复制到 result 数组。

MergeArrayExample1.java

输出

[23, 45, 12, 78, 4, 90, 1, 77, 11, 45, 88, 32, 56, 3]

让我们看另一个示例,其中我们指定了 source_array、destination、dest_position、source_position 和 length。我们可以根据指定的​​位置和长度合并数组。

示例

MergeArrayExample2.java

输出

source_array: 11 22 33 44 55 98 76 54 60 
sourcePos: 2
dest_array: 66 77 88 99 22 67 21 90 80 70 
destPos: 4
len: 3
Resultant array: 66 77 88 99 33 44 55 90 80 70

不使用 arraycopy() 方法

System.arraycopy() 方法是 Java 中用于在数组之间复制元素的有效本地方法。它处理类型安全、边界检查,并且由于其底层实现,其复制操作比手动循环快得多。如果不使用 System.arraycopy(),则必须手动循环遍历源数组以将元素复制到目标数组,这效率较低且更容易出错,尤其是对于大型数组。这是一个使用循环手动复制元素的简单示例:

合并两个数组的示例

在以下示例中,我们初始化了两个整数类型的数组 firstArray 和 secondArray。手动将这两个数组的每个元素复制到 mergedArray,并使用 Array 类的 toString() 方法将其转换为 String。

MergeArrayExample3.java

输出

[56, 78, 90, 32, 67, 12, 11, 14, 9, 5, 2, 23, 15]

使用 Collections

使用 Java Collections Framework 提供了一种灵活高效的方式来管理对象组。ArrayList、LinkedList、HashSet 和 HashMap 等集合提供了动态数据结构,可以根据需要增长或缩小,而固定大小的数组则不行。它们提供了用于添加、删除和操作元素的内置方法,使排序、搜索和合并等任务更简单、更高效。

例如,ArrayList 允许动态调整大小并提供 add()、remove() 和 get() 等方法。Collections 还支持泛型,确保编译时的类型安全。可以使用 addAll() 等方法轻松合并两个集合。

Java 中合并两个数组的示例

在以下示例中,我们初始化了两个 String 类型的数组 str1 和 str2。然后,我们使用 Arrays.asList() 方法创建了 str1 的列表视图。现在,我们创建了 str2 的列表视图并将 str2 的所有元素添加到列表中。再次执行从列表到数组的转换,并将结果数组存储到 str3 变量中。

MergeArrayExample4.java

输出

[A, E, I, O, U]

Java Stream API

Stream.of() 方法

Stream 接口的 Stream.of() 方法返回一个顺序流,其元素为指定的值。

语法

其中,T 是流元素的类型。该方法接受 values(新流的元素)。

Stream.flatMap() 方法

Stream.flatMap() 方法是 Stream 接口的方法。它返回一个由结果组成的流。

语法

其中 R 是新流的元素类型。该方法接受一个 mapper(应用于每个元素以生成新值流的函数)作为参数。

Stream.toArray() 方法

Stream 接口的 Stream.toArray() 方法返回一个包含流中元素的数组。

语法

使用 Stream API 合并两个数组的示例

MergeArrayExample5.java

输出

Merged array: [13, 12, 11, 6, 9, 3, 78, 34, 56, 67, 2, 11, 7]

最佳实践

  • 边界检查:始终确保指定的索引和长度不会超出数组的边界。
  • 类型兼容性:确保源数组和目标数组的类型兼容,以避免 ArrayStoreException。
  • 空值检查:始终检查 null 数组以避免 NullPointerException。
  • 一致的命名:使用清晰且具有描述性的数组名称,以提高代码的可读性和可维护性。
  • 封装:将数组封装在类或方法中,以控制访问并防止意外修改。
  • 不可变数组:在适当时考虑使用不可变或只读数组,以防止意外更改。
  • 性能优化:优化数组操作的效率,特别是对于大型数组或性能敏感的应用程序。
  • 文档和注释:提供清晰的文档和注释,以解释与数组相关的代码的目的、用法和约束。

结论

System.arraycopy() 方法是在 Java 中复制数组元素的通用且高效的工具。通过了解其参数、处理异常以及知道何时使用它,我们可以有效地管理 Java 应用程序中的数组操作。无论是合并数组、复制子数组还是移动元素,System.arraycopy() 都为这些任务提供了可靠的解决方案。


下一个主题Java 教程