System.arraycopy 不去重,仅高效搬运内存;去重需独立设计逻辑(如HashSet、双指针),arraycopy 仅用于最终结果拷贝,确保安全、零开销收尾。

System.arraycopy 本身不直接去重,它只是高效搬运内存块。真正实现“快速去重”,关键在于把它用在合适的位置——作为去重逻辑完成后的**结果落盘工具**,而不是去重算法本身。它的价值体现在:避免手写循环拷贝、零对象创建开销、边界强校验、支持原数组复用临时空间。
去重逻辑仍需独立设计
arraycopy 不判断重复,也不比较元素。所有去重决策(比如哪个元素该保留、是否已存在)必须由你提前算好。常见策略包括:
- 双层循环逐个比对(适合小数组、无序、原始类型)
- 用 HashSet 或 LinkedHashSet 收集唯一值(推荐,O(n) 时间)
- 对有序数组用双指针原地跳过重复(空间 O(1),但要求输入已排序)
无论选哪种,最终得到的都是一个“有效元素序列”(通常暂存在临时数组或集合中),这时 arraycopy 才派上用场。
用 arraycopy 快速收口结果数组
去重后你知道有效长度(比如 index=7),但临时数组可能按最大长度分配(如 new int[original.length])。这时用 arraycopy 拷贝前 index 个元素到新数组,是最轻量、最安全的方式:
int[] temp = new int[original.length]; // 临时缓冲 // ... 去重逻辑填充 temp[0..index-1] int[] result = new int[index]; System.arraycopy(temp, 0, result, 0, index); // 一次到位,无循环,无越界风险
相比 for 循环逐个赋值,它省去 JVM 的循环控制、边界检查和字节码解释开销,尤其在 index 较大时优势明显。
合并+去重场景中的高效衔接
两个数组合并再去重时,arraycopy 可先完成拼接,再交由 Set 处理:
- 用两次 arraycopy 把 arr1 和 arr2 拼成 mergedArray(比 for 或 Stream.concat 更快)
- 将 mergedArray 全部塞进 LinkedHashSet,自动去重并保序
- 最后用 arraycopy 把 set 转回 int[]:遍历 set 写入 temp 数组,再用 arraycopy 拷贝到 final 数组
注意:Set 转数组不能直接 arraycopy(类型不匹配),但遍历写入 temp 后那一步,arraycopy 就是不可替代的收尾动作。
避开常见陷阱
实际用 arraycopy 收尾时,这几个细节容易出错:
- srcPos 和 destPos 都从 0 开始,length 必须等于有效元素个数,不能用原数组 length
- 目标数组 result 必须预先 new 出正确大小;arraycopy 不负责扩容
- 不要对 null 或空数组调用;应在调用前做 if (index == 0) 短路处理
- 基本类型数组(int[]、byte[])之间不能混用;Object[] 拷到 String[] 会在运行时校验类型
它快,但只快在“搬运”这一环——前面去重算得慢,后面搬得再快也白搭。把 arraycopy 当作去重流水线里最后一道高速传送带,才是正解。

















