System.arraycopy是拼接原始类型数组最快零分配方式;需先计算总长再逐段复制,注意源/目标偏移量和长度不越界,避免ArrayIndexOutOfBoundsException。

用 System.arraycopy 拼接原始类型数组最直接
原始类型数组(如 int[]、byte[])不能用泛型集合操作,System.arraycopy 是底层最快、零对象分配的方式。它不创建中间集合,也不触发装箱,适合性能敏感或大数组场景。
常见错误是目标数组长度算错,或源偏移量越界,抛出 ArrayIndexOutOfBoundsException;另一个坑是把 srcPos 和 destPos 弄反——它们都指“从第几个元素开始复制”,不是起始地址。
- 先用
Arrays.stream(arrays).mapToInt(a -> a.length).sum()算总长,别手写循环累加 - 每次调用
System.arraycopy(src, srcPos, dest, destPos, length)前,确认srcPos + length 且 <code>destPos + length - 对
int[][]这类二维数组,System.arraycopy只复制引用,不是深拷贝;要深拼接得逐行复制
int[] a = {1, 2};
int[] b = {3, 4, 5};
int[] result = new int[a.length + b.length];
System.arraycopy(a, 0, result, 0, a.length);
System.arraycopy(b, 0, result, a.length, b.length); // 注意 destPos = a.length
用 Stream.of().flatMap() 拼接引用类型数组更简洁
对 String[]、Integer[] 这类引用类型数组,Stream 扁平化是可读性与开发效率的平衡点。它本质是把每个数组转成 Stream 再合并,底层仍会创建临时对象,但代码少、逻辑直白。
容易踩的坑是误用 Arrays.stream() 直接传二维数组:比如 Arrays.stream(stringArrays) 返回的是 Stream<string></string>,不是 Stream<string></string>,必须用 flatMap 解一层。
立即学习“Java免费学习笔记(深入)”;
- 必须用
Stream.of(arr1, arr2, arr3).flatMap(Arrays::stream),不能写成Arrays.stream(new String[][]{arr1, arr2}) - 如果数组可能为
null,先过滤:Stream.of(arr1, arr2).filter(Objects::nonNull).flatMap(Arrays::stream) - 结果转回数组时,注意类型推导:
toArray(String[]::new)不能省略构造器引用,否则返回Object[]
String[] a = {"x", "y"};
String[] b = {"z"};
String[] result = Stream.of(a, b).flatMap(Arrays::stream).toArray(String[]::new);
System.arraycopy 不支持泛型数组,别硬套
写 T[] 泛型方法时,想用 System.arraycopy 拼接?编译会报错:因为擦除后 T[] 是 Object[],而 System.arraycopy 要求明确的组件类型。这不是限制,是 JVM 类型模型决定的。
典型错误现象是编译失败提示 “incompatible types: Object[] cannot be converted to T[]”,或者绕过编译强行用 (T[]) new Object[n] 导致运行时 ClassCastException。
- 泛型数组拼接唯一安全方式是用
Stream+toArray,靠Supplier构造正确类型数组 - 若坚持用数组工具,改用
ArrayList中转:先收集再toArray(new T[0]),JDK 11+ 支持该惯用法 - 不要用
Arrays.copyOf叠加,它每次新建数组,时间复杂度 O(n²),比System.arraycopy多一次拷贝
小数组用 Stream,大数组或原始类型优先 System.arraycopy
没有银弹。10 个元素以内,两种方式性能差异可忽略;但 10 万级 int[] 拼接,System.arraycopy 耗时通常在纳秒级,而 Stream 会触发多次对象分配和 GC 压力。
真正容易被忽略的是数组组件类型的隐式转换成本:比如把 Integer[] 用 Stream 拼接再转 int[],会额外经历拆箱;而 System.arraycopy 对引用类型只是复制指针,对原始类型才是复制值。
- 检查最终目标类型:要原始类型数组?选
System.arraycopy;要引用类型且后续还要流式处理?Stream更连贯 - Android 开发注意:旧版 ART 对
Stream优化弱,System.arraycopy更稳 - 如果拼接逻辑在 hot path(如网络包组装、音视频帧处理),哪怕多写几行,也优先手写
System.arraycopy









