System.arraycopy 不参与排序逻辑,而是归并排序合并阶段高效搬移已排序子段的核心工具,通过批量拷贝避免逐个赋值的性能损耗和边界错误,需确保源目标区间连续、空间充足、长度准确,并注意重叠处理、越界校验、类型兼容及小段开销等实操要点。

System.arraycopy 本身不参与排序逻辑,也不比较元素大小,但它在归并排序(Merge Sort)等分治类排序的合并阶段中,是实现高效、低开销数据搬移的核心工具。关键不是“用它排序”,而是用它精准、零冗余地完成已排好序子段的合并搬运,避免逐个赋值带来的性能损耗和边界错误。
合并两个有序子数组时的分段拷贝
归并排序中,常需将左右两个已排序的子数组(如 arr[low..mid] 和 arr[mid+1..high])合并为一个有序段。手动循环合并虽直观,但 arraycopy 可在局部连续、无重叠前提下批量搬运整块数据,显著提升吞吐量。
例如:
- 左段
[1,3,5]在arr[0..2] - 右段
[2,4,6,8]在arr[3..6] - 目标是把合并结果写入临时数组
temp[]或原数组指定位置
此时若某次比较后确定要搬入右段连续 3 个元素(如 2,4,6),可直接:
System.arraycopy(arr, 3, temp, writePos, 3); // 一次搬完,非三次赋值 writePos += 3;
✅ 前提:源区间连续、目标位置有足够空间、长度准确。
❌ 不适用:边比较边插入且目标区与源区重叠又方向不明时(此时仍需双指针+单元素赋值)。
原地归并中的安全覆盖策略
某些优化场景要求“原地合并”(不额外分配 O(n) 空间),这时 arraycopy 的重叠处理能力就很重要:
- 若需将
arr[i..j]整体右移到arr[k..k+(j-i)],且k > j(右移不重叠),直接调用即可,JVM 自动正向拷贝; - 若
k < i且存在重叠(如左段前移覆盖右段),JVM 会自动倒序执行,防止未读数据被覆盖; - 示例:
System.arraycopy(arr, 2, arr, 0, 4)把索引 2~5 的元素前移到 0~3 —— 安全,无需手写循环。
⚠️ 注意:arraycopy 不判断业务逻辑,只保内存安全。你必须确保 srcPos、destPos、length 的组合符合实际合并意图,否则搬错位置会导致排序失败。
避免常见陷阱的实操要点
-
不假设“自动截断”:
srcPos + length > src.length会立即抛ArrayIndexOutOfBoundsException,必须提前校验。建议用Math.min(length, src.length - srcPos)控制实际拷贝量。 -
合并到目标数组时,destPos 是累加偏移:比如先搬左段 3 个到
temp[0],再搬右段 4 个,第二句的destPos必须是3,不是0。 -
类型必须兼容:
int[]不能拷给String[];若用Object[]做通用缓冲,确保运行时元素类型一致,否则抛ArrayStoreException。 -
小段搬运不划算:单次
length < 32时,JNI 调用开销可能抵消收益;归并中可设阈值(如length >= 64)才启用arraycopy,小段仍用循环。
不复杂但容易忽略。

















