`
xuyuanshuaaa
  • 浏览: 394671 次
  • 性别: Icon_minigender_1
  • 来自: 大连
社区版块
存档分类
最新评论

java的system.arraycopy()方法

阅读更多
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
01.public static void arraycopy(Object src,     
02.                             int srcPos,     
03.                             Object dest,     
04.                             int destPos,     
05.                             int length)     
06.    从指定源数组中复制一个数组,复制从指定的位置开始,到目标数组的指定位置结束。从 src 引用的源数组到 dest 引用的目标数组,数组组件的一个子序列被复制下来。被复制的组件的编号等于 length 参数。源数组中位置在 srcPos 到 srcPos+length-1 之间的组件被分别复制到目标数组中的 destPos 到 destPos+length-1 位置。  

它是个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中被访问了。
分享到:
评论
2 楼 surpassno 2016-07-09  
南冠楚囚 写道
如果是复制一个一位数组,那么改变复制后的数组并不影响原数组。

你用的String是不可变的类,说明不了问题。
   s2[6] = "假设蒙大拿州"; 
   s2[7] = "假设蒙特利尔市"; 
   s2[8] = "假设Montreal商学院";
这只是数组元素s2[6]引用到了新的对象 "假设蒙大拿州" ,而不是在改变原有的s2[6]所引用的对象,当然不会对s1[6]有影响。s1[6]依然指向原有的对象 "不知道哪个州" 。

我用了一个可变类试了一下:
class MyClass{
public int field;
public MyClass(int field){
this.field=field;
}
}
public class Solution {

    public static void main(String[] args)
    {
    MyClass a=new MyClass(1);
    MyClass b=new MyClass(2);
    MyClass c=new MyClass(3);
    MyClass[] s1={a,b,c};
    MyClass[] s2=new MyClass[3];
   
   
    System.arraycopy(s1, 0, s2, 0, s1.length);
    s2[0].field=8888;
    System.out.println(s1[0].field);
    System.out.println(s1[1]==s2[1]);
    System.out.println(s1==s2);
    }
}
输出:8888
      true
      false


  这是对的观点,不过博主也很专研啊.
1 楼 南冠楚囚 2015-08-05  
如果是复制一个一位数组,那么改变复制后的数组并不影响原数组。

你用的String是不可变的类,说明不了问题。
   s2[6] = "假设蒙大拿州"; 
   s2[7] = "假设蒙特利尔市"; 
   s2[8] = "假设Montreal商学院";
这只是数组元素s2[6]引用到了新的对象 "假设蒙大拿州" ,而不是在改变原有的s2[6]所引用的对象,当然不会对s1[6]有影响。s1[6]依然指向原有的对象 "不知道哪个州" 。

我用了一个可变类试了一下:
class MyClass{
public int field;
public MyClass(int field){
this.field=field;
}
}
public class Solution {

    public static void main(String[] args)
    {
    MyClass a=new MyClass(1);
    MyClass b=new MyClass(2);
    MyClass c=new MyClass(3);
    MyClass[] s1={a,b,c};
    MyClass[] s2=new MyClass[3];
   
   
    System.arraycopy(s1, 0, s2, 0, s1.length);
    s2[0].field=8888;
    System.out.println(s1[0].field);
    System.out.println(s1[1]==s2[1]);
    System.out.println(s1==s2);
    }
}
输出:8888
      true
      false

相关推荐

    System.arraycopy实现数组之间的复制

    在Java编程语言中,`System.arraycopy()`是一个非常实用且高效的方法,用于在数组之间复制元素。此方法属于`java.lang.System`类,并且是一个静态方法,这意味着可以直接通过`System`类名调用它,而无需创建`System`...

    System.arraycopy和Arrays.copyOf

    `System.arraycopy` 和 `Arrays.copyOf` 都是Java中用于复制数组的方法,但它们在使用和处理异常情况上有所不同。这两个方法在处理数组复制时,提供了便利和效率,但各有其适用场景。 `System.arraycopy` 是一个...

    详解Java合并数组的两种实现方式

    在Java中有多种方式可以实现数组合并,本文将介绍两种常见的实现方式,即使用System.arraycopy()方法和ArrayUtils.addAll()方法。 1. System.arraycopy()方法 System.arraycopy()方法是Java提供的一种本地方法,...

    合并两个数组的Java程序.docx

    本篇文章将介绍两种方法来合并两个数组,一种是使用Java内置的`System.arraycopy()`函数,另一种是不使用预定义函数,而是通过手动遍历来实现。 首先,让我们详细讨论使用`System.arraycopy()`的方法。这个方法是从...

    「java三种字符数组合并的方法」.docx

    在第三个方法中,我们使用了 System.arraycopy 方法来实现数组合并。我们首先创建了一个新的字符串数组 c,然后使用 System.arraycopy 方法将数组 a 和 b 的元素复制到数组 c 中。 代码实现: ```java public ...

    java三种字符数组合并的方法.doc

    这三种方法分别是:使用循环手动填充新数组、利用`List`集合进行合并再转换为数组以及直接使用`System.arraycopy()`方法。此外,还将涉及如何合并不同类型的数组,如字符数组与整型数组。 ### 方法一:使用循环合并...

    Java ArrayList.add 的实现方法

    需要注意的是,在 add(int index, E element) 方法中,我们使用 System.arraycopy 方法来复制数组元素,这是一个 native 方法,它的实现是基于 C++ 语言的。很多人认为 System.arraycopy 方法是调用底层的 memcpy ...

    Java数组倒置.zip

    数组倒置也可以使用Java的`System.arraycopy`方法来实现,这种方法更加简洁高效: ```java public class C { public static void main(String[] args) { int[] array = {1, 2, 3, 4, 5}; reverseArray(array); ...

    2022年计算机二级考试java章节辅导数组元素的复制.docx

    数组元素的复制通常有两种方式:使用循环进行逐个元素的复制,以及使用Java提供的`System.arraycopy()`方法。 首先,我们来探讨一下使用循环复制数组元素的方法。例如,当我们有一个已经初始化的数组`a`,我们想要...

    Java数组倒置源代码

    另一种方法是使用Java的`System.arraycopy()`函数,它可以高效地复制数组的一部分。在数组倒置的情况下,我们可以先创建一个临时数组,然后使用`arraycopy()`将原数组的后半部分复制到临时数组,再将原数组的前半...

    java反射操作父类所有属性和方法

    ### Java反射操作父类所有属性和方法 #### 一、引言 在Java编程语言中,反射(Reflection)是一项强大的特性,它允许程序在运行时动态地获取类的信息,并能够直接操作这些信息。通过反射,我们可以获取类的字段、...

    第03讲 JAVA数组.ppt

    赋值操作(如`bb = aa`)只会让两个数组引用指向同一块内存,而`System.arraycopy()`方法则会真正复制数组的内容到另一块内存。 在处理大量数据时,Java集合框架中的`ArrayList`和`LinkedList`等集合类通常比数组更...

    java中两个byte数组实现合并的示例

    总结来说,Java中合并两个`byte`数组可以通过创建新的数组并使用`System.arraycopy()`方法来实现。如果需要进一步处理合并后的数组,如反转或加密,可以分别使用自定义函数或Java内置的加密库。这些操作在处理二进制...

    java.lang.System类.pdf

    Java中的`java.lang.System`类是Java核心库中不可或缺的一部分,它是系统级操作的主要入口点。这个类提供了很多静态字段和...理解并熟练使用`System`类的各种方法,可以帮助开发者更好地操控Java程序与系统资源的交互。

    java高端技术课程--Java数组如何实现复制

    Java提供了System类的arraycopy()方法,它是进行数组复制的最直接和高效的方式。该方法接受五个参数:源数组、源数组起始位置、目标数组、目标数组起始位置和复制的元素数量。例如: ```java int[] srcArray = {1...

    Java程序优化大全[参照].pdf

    `System.arraycopy()`是Java提供的一个高效的方法,用于复制数组。相比使用循环逐个元素复制,`System.arraycopy()`在底层实现上更优化,能提供更好的性能。例如,如果你需要复制一个整型数组,避免使用for循环,...

    消费者终端云服务java-A-2021.pdf

    在Java数组复制方法中,效率最高的方法是System.arraycopy。 提到的Java代码中存在空指针异常的情况,但通过测试发现这段代码可以正常运行,因为Java的静态方法可以在类被加载的时候调用,即使它所属的对象是空...

    java performance12

    这里提到了可以使用 `java.util.Arrays` 和 `java.util.Collections` 提供的方法来实现高效拷贝。下面详细介绍这两种方法: - **使用 `java.util.Arrays.copyOf()`:** `java.util.Arrays.copyOf()` 方法是拷贝...

    大学专业试卷《JAVA》试卷B.doc

    * 在JAVA中,可以使用System.arraycopy()方法将一个数组的元素复制到另一个数组中。 * System.arraycopy()方法的参数包括源数组、源数组的起始索引、目标数组、目标数组的起始索引和要复制的元素个数。 例如,在...

Global site tag (gtag.js) - Google Analytics