资讯专栏INFORMATION COLUMN

System.arraycopy方法的简短总结

Michael_Lin / 3496人阅读

摘要:相比遍历复制,此方法更加高效。原因很简单,该方法使用内存块整体读取与复制,相比的遍历寻址来说自然会快,不过这个速度优势在数组成员比较多的时候才会有较明显的体现。下面贴出方法中关键部分的方法代码

API使用场景

在JDK研发团队的开发过程中,对集合的操作过程中常会使用到此方法。

API参数
public static native void arraycopy(
       Object src,  //源数组
       int srcPos,  //源数组的读取起始位置
       Object dest, //目标数组
       int destPos, //目标数据中的写入起始位置
       int length   //要复制的数组元素的数量
       );
Functions

将指定源数组的数组从指定位置复制到目标数组的指定位置。数组组件的子序列由src引用的源数组复制到dest引用的目标数组。复制的组件数等于length。源序列中从srcPos到srcPos+length-1的序列复制到目标序列的destPos到destPos+length-1位置。

如果src和dest参数引用的是相同的数组对象,则首先把源数组srcPos到srcPos+length-1的组件复制到具有与此相同长度的临时数组里,然后再把临时数组的内容复制到目标数组destPos到destPos+length-1位置。

如果dest为null,则抛出NullPointerException;如果src为空,则抛出NullPointerException,并且不修改目标数组。

抛出ArrayStoreException的情况(前7种情况不会修改dest):
1)src参数指向的不是数组对象
2)dest参数指向的不是数组对象
3)src参数和dest参数指向的对象类型不是同一种基本类型的数组
4)src参数指向由原始组件类型组成的数组,dest参数指向由引用组件类型组成的数组
5)dest参数指向由原始组件类型组成的数组,src参数指向由引用组件类型组成的数组
6)srcPos+length>src.length
7)destPos+length>dest.length
8)对于任意i满足:srcPos <= i <= (srcPos+length-1),src.get(i)无法转换为dest的成员类型。(这种情况下,令k为小于length的非负整数,假设此时使src[srcPos+k]不能转换为目标数组的成员类型,当抛异常时srcPos到srcPos+k-1的源数组成员已经通过destPos+k-1被复制到目标数组的destPos位置,目标数组的剩余位置不会被修改。这种情况仅适用于两个数组都具有引用类型的成员类型的情况)

方法特性

1、总的来说,复制方式属于浅复制

复制的过程只是引用变量的二次传递。

一维数组的复制:属性值传递,修改则不会影响副本

二维数组的复制:复制的是第一维的引用列表,副本和原数组的指向是相同的堆地址,这个时候,值变动的影响是双向的

2、此方法不是线程安全的,必要时要加锁限制。
3、相比for遍历复制,此方法更加高效。

原因很简单,该方法使用内存块整体读取与复制,相比for的遍历寻址来说自然会快,不过这个速度优势在数组成员比较多的时候才会有较明显的体现。下面贴出native方法中关键部分copy的方法c++代码:

void _Copy_conjoint_jints_atomic(jint* from, jint* to, size_t count) {
    if (from > to) {
      jint *end = from + count;
      while (from < end)
        *(to++) = *(from++);
    }
    else if (from < to) {
      jint *end = from;
      from += count - 1;
      to   += count - 1;
      while (from >= end)
        *(to--) = *(from--);
    }
}

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/67899.html

相关文章

  • 从源码看Java集合之ArrayList

    摘要:集合之吃透增删查改从源码看初始化以及增删查改,学习。一初始化无参的构造器可以看到这个构造器初始化了一个空数组。指定长度的构造器这个构造器显式的指明了数组的长度,其实如果小于的话,在添加第一个元素的时候还是会扩充到长度为的数组。 Java集合之ArrayList - 吃透增删查改 从源码看初始化以及增删查改,学习ArrayList。 先来看下ArrayList定义的几个属性: priva...

    seasonley 评论0 收藏0
  • Java 面试准备

    摘要:网站的面试专题学习笔记非可变性和对象引用输出为,前后皆有空格。假定栈空间足够的话,尽管递归调用比较难以调试,在语言中实现递归调用也是完全可行的。栈遵守规则,因此递归调用方法能够记住调用者并且知道此轮执行结束之返回至当初的被调用位置。 ImportNew 网站的Java面试专题学习笔记 1. 非可变性和对象引用 String s = Hello ; s += World ; s.tr...

    chanjarster 评论0 收藏0
  • System.arraycopy方法解释

    摘要:源数组源数组要复制的起始位置目标数组将原数组复制到目标数组目标数组起始位置从目标数组的哪个下标开始复制操作复制源数组的长度例子如下源数组为目标数组为开始执行数组复制操作将源数组从数组下标开始的位长度的数组复制到目标数组从下标为的位置开始复制 **/* * @param src the source array.源数组 * @param srcPos ...

    yexiaobai 评论0 收藏0
  • 数组

    摘要:二数组扩容及拷贝数组的扩容数组是根据固定容量创建的,在必要的时候我们需要对数组进行扩容初始长度为下面决定需要对数组进行扩容对原数组进行内容拷贝在对数组进行拷贝时除了利用循环遍历数组元素进行拷贝外,推荐使用更高效的方法。 PS:如果觉得文章有什么地方写错了,哪里写得不好,或者有什么建议,欢迎指点。 一、认识数组 数组是一种线性表数据结构。它用一块连续的内存空间,来存储相同类型的一组数据。...

    Yuqi 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<