`

【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中被访问了。
分享到:
评论

相关推荐

    com.google.zxing.client.j2se.jar下载

    zxing/zxing-j2se-1.7.jar包, ...com.google.zxing.client.j2se.BufferedImageLuminanceSource.class com.google.zxing.client.j2se.CommandLineRunner.class com.google.zxing.client.j2se.Config.class ...

    J2SE1.6.chm 帮助文档

    J2SE1.6.chm 官方帮助文档,chm格式,使用更加方便

    J2SE6.0.chm api

    J2SE6.0.chm api

    j2se6.rar_J2se6

    “j2se6.chm”文件是这个压缩包中的核心资源,它包含了完整的J2SE6 API文档,是开发者查询类库、方法和接口的宝典。通过这个文件,开发者可以快速查找类的详细信息,了解其构造函数、方法、常量等,这对于编写Java...

    01_J2SE概述.pdf

    自1995年发布JDK 1.0以来,Java经历了多个版本的发展,包括JDK 1.1、JDK 1.2(将Java更名为Java 2),并将其分为J2SE(Java标准版)、J2EE(Java企业版)、J2ME(Java微型版)。2005年Java迎来了十周年,Java 2平台...

    j2se代码.zip

    Java 2 Standard Edition (J2SE) 是 Java 平台的核心部分,主要用于开发桌面应用程序。这个压缩包"j2se代码.zip"显然包含了与 Java 编程相关的源代码,非常适合那些刚开始学习 Java 的初学者。这里我们将深入探讨 ...

    j2se6.part3.chm

    j2se6.part3.chm 英文版的非中文版

    j2se6.part1.chm

    j2se6.part1,chm格式,英文版的

    j2se6.rar_Looking Up

    标题“j2se6.rar_Looking Up”和描述“api for looking up java codes”暗示了这个压缩包可能包含了与Java SE 6相关的API文档,特别是关于查找或搜索Java代码方面的内容。Java SE(标准版)是Java平台的核心部分,...

    zxing二维码中j2se的两个包

    com.google.zxing.client.j2se.BufferedImageLuminanceSource和com.google.zxing.client.j2se.MatrixToImageWriter,亲测可用

    j2se.rar_j2EE api_j2se_j2se.c

    这个压缩包"j2se.rar_j2EE api_j2se_j2se.c"显然包含了与 J2EE 和 Java Standard Edition (J2SE) 相关的资源,尤其是 J2EE 的API文档以及可能的 J2SE 相关代码示例。 J2SE 是 Java 平台的核心部分,它为桌面应用和...

    zxing-j2se01.7.jar

    标题中的"zxing-j2se01.7.jar"是ZXing Java版本的一个特定发行版,版本号为1.7。这个JAR文件包含了ZXing库的所有Java类和资源,可供Java开发者在桌面应用或服务器端项目中使用,实现条形码的读取和生成。如果你在...

    j2se5.rar_J2SE 架构_j2se

    6. **变量推断(varargs)**:允许方法参数接受可变数量的参数,语法上用三个点(...)表示,简化了方法调用。 7. **静态导入**:允许一次性导入某个包中的所有静态成员,避免了多次import语句,使代码更易读。 8....

    j2se6.chm.zip

    标题中的"j2se6.chm.zip"表明这是一个关于Java 2 Standard Edition (J2SE) 6的压缩包文件,通常包含一个.chm(Microsoft Compiled HTML Help)格式的文档,这种格式常用于技术手册和指南。CHM文件集成了HTML页面,...

    J2SE课程.rar

    Java Standard Edition(简称J2SE)是Java平台的核心部分,为开发桌面应用程序和服务器应用程序提供了基础框架。这个压缩包文件“J2SE课程.rar”显然包含了一套完整的J2SE学习资源,旨在帮助初学者或者有志于深入...

    [Java参考文档].J2SE6.0_CN.CHM

    [Java参考文档].J2SE6.0_CN.CHM,由于文件过大,所以划分了两个rar文件

    J2SE总结.txt

    因为这是java的总结需要有点基础的看,要不看不懂,不需要大家太多积分,如果感觉哪写的不对留言哈

    java j2se6.chm

    自学java必备资源,高级教师推荐,欢迎下载!

    j2se6.chm+JDK_API_1.6_zh_中文.CHM+jdk_api_1.7.chm

    这些API文档是Java开发者的重要参考资料,通过查阅它们,开发者可以了解每个类、接口和方法的详细功能、使用示例和注意事项。无论是初学者还是经验丰富的开发者,都应该熟悉并熟练运用这些API来提高编程效率和代码...

Global site tag (gtag.js) - Google Analytics