`

【J2SE】System.arraycopy()方法

    博客分类:
  • J2SE
 
阅读更多
java.lang.System的静态方法arraycopy()可以实现数组的复制,讲课的老师说这个方法效率比较高,如果数组有成千上万个元素,那么用这个方法,比用for语句循环快不少。于是我试了试,发现以下问题。

如果是复制一个一位数组,那么改变复制后的数组并不影响原数组。但是如果复制一个二维数组,那么改变其中任何一个数组,那么另一个的值也发生了变化。开始不是很明白,后来上网查了查资料,理解了其中奥妙。

java其实没有二维数组的概念,平常实现的二维数组只是元素是一维数组的一维数组,而数组也是引用类型,继承自Object类。数组是new出来的。这些性质也就导致arraycopy()二维数组时出现的问题。

如果是一维数组,那么元素都是基础类型(如int,double等),使用arraycopy()方法后,是把原数组的值传给了新数组,属于值传递。而如果是二维数组,数组的第一维装的是一个一维数组的引用,第二维里是元素数值。对二维数组应用arraycopy()方法后,第一维的引用被复制给新数组的第一维,也就是两个数组的第一维都指向相同的“那些数组”。而这时改变其中任何一个数组的元素的值,其实都修改了“那些数组”的元素的值,所以原数组和新数组的元素值都一样了。

OK,就是这样。

不明白可以看看这个例子:

public class TestArrayCopy {

/**
* @param args
*/
public static void main(String[] args) {
   // TODO 自动生成方法存根
  
   String[] s1 = {"中国","山西","太原","TYUT","zyy","加拿大","不知道哪个州","不知道哪个市","不知道哪个学校","yxf"};
   String[] s2 = new String[10];
   System.arraycopy(s1, 0, s2, 0, 10);
   s2[6] = "假设蒙大拿州";
   s2[7] = "假设蒙特利尔市";
   s2[8] = "假设Montreal商学院";
  
   System.out.println("This is s1");
   for(int i = 0;i < s1.length ;i++){
    System.out.print(s1[i] + ",");
   }
  
   System.out.println("\nThis is s2");
   for(int i = 0;i < s2.length ;i++){
    System.out.print(s2[i] + ",");
   }
  
   String[][] s3 = {{"中国","山西","太原","TYUT","zyy"},{"加拿大","不知道哪个州","不知道哪个市","不知道哪个学校","yxf"}};
   String[][] s4 = new String[s3.length][s3[0].length];
   System.arraycopy(s3, 0, s4, 0, s3.length);
  
   System.out.println("\nThis is original s3");
   for(int i = 0;i < s3.length ;i++){
    for(int j = 0; j< s3[0].length ;j++){
     System.out.print(s3[i][j] + ",");
    }
   }
  
   s4[1][1] = "假设蒙大拿州";
   s4[1][2] = "假设蒙特利尔市";
   s4[1][3] = "假设Montreal商学院";
  
   System.out.println("\nThis is s3 after s4 has changed.");
   for(int i = 0;i < s3.length ;i++){
    for(int j = 0; j< s3[0].length ;j++){
     System.out.print(s3[i][j] + ",");
    }
   }
  
   System.out.println("\nThis is s4");
   for(int i = 0;i < s4.length ;i++){
    for(int j = 0; j < s4[0].length ; j++){
     System.out.print(s4[i][j] + ",");
    }
      
   }
}

}




结果:

This is s1
中国,山西,太原,TYUT,zyy,加拿大,不知道哪个州,不知道哪个市,不知道哪个学校,yxf,
This is s2
中国,山西,太原,TYUT,zyy,加拿大,假设蒙大拿州,假设蒙特利尔市,假设Montreal商学院,yxf,
This is original s3
中国,山西,太原,TYUT,zyy,加拿大,不知道哪个州,不知道哪个市,不知道哪个学校,yxf,
This is s3 after s4 has changed.
中国,山西,太原,TYUT,zyy,加拿大,假设蒙大拿州,假设蒙特利尔市,假设Montreal商学院,yxf,
This is s4
中国,山西,太原,TYUT,zyy,加拿大,假设蒙大拿州,假设蒙特利尔市,假设Montreal商学院,yxf,

arraycopy的实现方法:
其中 Arrays.copy是JDK1.6中引用的新方法。它调用了System.arraycopy完成相关数组的复制。
在JDK1.6中ArrayList的相关add remove等操作都是调用System.arraycopy来对其底层的Object[]elementData数组进行操作的。
LinkedList则使用一个Entry的内部类,其有指向next和previous的引用保存元素,它的遍历则先计算出所需index和size>>1(以为后的大小),确定是通过previous还是next遍历。
System.arraycopy
它是个native方法,测试结果表明,

当数组很小,但存是调用次数多的话。

使用它复制数组并不比for循环手工复制数组快。
但是如果是数组比较大,那么使用System.arraycopy会比较有优势,因为其使用的是内存复制,省去了大量的数组寻址访问等时间。
     native方法:
Java不是完美的,Java的不足除了体现在运行速度上要比传统的C++慢许多之外,Java无法直接访问到操作系统底层(如系统硬件等),为此Java使用native方法来扩展Java程序的功能。

  可以将native方法比作Java程序同C程序的接口,其实现步骤:

  1、在Java中声明native()方法,然后编译;

  2、用javah产生一个.h文件;

  3、写一个.cpp文件实现native导出方法,其中需要包含第二步产生的.h文件(注意其中又包含了JDK带的jni.h文件);

  4、将第三步的.cpp文件编译成动态链接库文件;

  5、在Java中用System.loadLibrary()方法加载第四步产生的动态链接库文件,这个native()方法就可以在Java中被访问了。
分享到:
评论

相关推荐

    J2SE_5.0_第05章_数组2.rar

    `System.arraycopy()`方法用于复制数组的一部分到另一个数组。而`Arrays.equals()`方法可以用来比较两个数组是否完全相同。例如: ```java int[] original = {1, 2, 3}; int[] copy = new int[original.length]; ...

    J2SE_5.0_第05章_数组1.rar

    1. 数组复制:可以使用System.arraycopy()方法复制数组的一部分或全部。 2. 数组比较:Java提供Arrays.equals()方法来比较两个数组是否完全相同,包括元素和长度。 五、数组的练习 提供的视频文件01_一维数组内存...

    J2SE基础复习提纲

    - **数组复制**: `System.arraycopy`方法可以高效地复制数组,如`System.arraycopy(src, srcPos, dest, destPos, length);`。 #### 七、面向对象编程基础 - **类与对象**: 类是对现实世界中一类事物的抽象描述,...

    Java实验.pdf

    同时,CopyArray.java演示了数组的使用,特别是`System.arraycopy()`方法,用于高效地复制数组元素。此方法可以用于在不同数组间快速移动或复制数据,这对于处理大量数据非常有用。 实验二:类封装与包管理 这个...

    Java实验.docx

    在`CopyArray.java`中,展示了如何使用`System.arraycopy()`方法进行数组的快速复制。这个方法可以从源数组的一部分复制到目标数组,参数包括源数组、起始位置、目标数组、目标起始位置和复制长度。 3. **类封装**...

    学生考试专用JAVA的试题.pdf

    - `System.arraycopy()` 方法用于数组间复制元素。 - `Runtime.getRuntime().exec()` 方法用于执行外部程序。 - `Thread.currentThread()` 返回当前正在执行的线程。 - `CPU`和`RAM`是计算机硬件资源。 - `...

    java面向对象编程知识点笔记整理与总结0

    - 数组截取:`System.arraycopy(源数组, 源起始位置, 目标数组, 目标起始位置, 复制长度);` - 数组扩容:`ary = Arrays.copyOf(ary, ary.length + 1);` #### 面向对象的三大原则 - **封装**:隐藏对象的属性和...

    新东方JAVA课程PPT课件 数组(下)

    如果需要值的拷贝,可以使用`System.arraycopy()`方法,它能高效地将一个数组的一部分或全部复制到另一个数组。 排序是数组处理中的常见任务。Java的`Arrays`类提供了一个静态的`sort()`方法,可以对一维数组进行...

    【05-面向对象(下)】

    加abstract修饰符,并把普通方法的方法体(也就是方法后花括号括起来的部分)全部去掉,并在方法后增加分号 即可。 抽象类的特征 •抽象类的特征:有得有失,得到了新能力,可以拥有抽象方法;失去了...

Global site tag (gtag.js) - Google Analytics