Arrays.copyOfRange是Java中高效截取数组的工具,底层调用System.arraycopy,时间复杂度O(n),起始索引from包含、结束索引to不包含,越界时自动补默认值或抛异常,推荐封装校验逻辑并避免Stream用于大数组。

Arrays.copyOfRange 是 Java 中专门用于从原数组中截取指定范围并生成新数组的高效工具,它底层直接调用 System.arraycopy,避免了手动循环复制,时间复杂度为 O(n),空间上仅分配目标区间长度的新数组,对大数组特别友好。
明确起始与结束索引的含义
该方法签名是:copyOfRange(T[] original, int from, int to),其中:
- from 是包含的起始下标(从 0 开始,含)
-
to 是不包含的结束下标(即复制到
to - 1为止) - 若
to > original.length,末尾自动补默认值(如 int 补 0,引用类型补 null) - 若
from < 0或to < from,会抛出ArrayIndexOutOfBoundsException
针对大数组的典型安全截取写法
为避免越界和逻辑错误,建议封装一层带校验的工具方法:
- 先判断
from和to是否合法:确保0 ≤ from ≤ to ≤ original.length - 使用
Math.min(to, original.length)防止越界(当 to 过大时自动截断) - 对空数组或 from == to 的情况,直接返回对应类型空数组(如
new int[0])
示例(int 数组):
int[] big = new int[10_000_000];int[] sub = Arrays.copyOfRange(big, 1000, 2000); // 快速拿到第 1000~1999 共 1000 个元素
与手动循环或 Stream 的性能对比
对千万级数组截取 10 万元素:
- copyOfRange:约 0.1~0.3 ms,JVM 内联优化 + 底层内存块拷贝
- for 循环逐个赋值:约 0.5~1.2 ms,有边界检查开销和解释执行成本
- Arrays.stream().skip().limit().toArray():约 8~15 ms,对象包装、装箱/拆箱、Stream 管道开销大,不推荐用于纯数值大数组
注意类型擦除下的泛型数组处理
对泛型集合转数组后截取,需显式传入运行时类型:
String[] arr = list.toArray(new String[0]);String[] part = Arrays.copyOfRange(arr, 100, 200); // 正确
// ❌ 不要写成 copyOfRange(list.toArray(), 100, 200),因 Object[] 无法自动转为 String[]

















