- 浏览: 45686 次
- 性别:
-
文章分类
最新评论
java.lang.System的静态方法arraycopy()可以实现数组的复制,讲课的老师说这个方法效率比较高,如果数组有成千上万个元素,那么用这个方法,比用for语句循环快不少。于是我试了试,发现以下问题。
如果是复制一个一位数组,那么改变复制后的数组并不影响原数组。但是如果复制一个二维数组,那么改变其中任何一个数组,那么另一个的值也发生了变化。开始不是很明白,后来上网查了查资料,理解了其中奥妙。
java其实没有二维数组的概念,平常实现的二维数组只是元素是一维数组的一维数组,而数组也是引用类型,继承自Object类。数组是new出来的。这些性质也就导致arraycopy()二维数组时出现的问题。
如果是一维数组,那么元素都是基础类型(如int,double等),使用arraycopy()方法后,是把原数组的值传给了新数组,属于值传递。而如果是二维数组,数组的第一维装的是一个一维数组的引用,第二维里是元素数值。对二维数组应用arraycopy()方法后,第一维的引用被复制给新数组的第一维,也就是两个数组的第一维都指向相同的“那些数组”。而这时改变其中任何一个数组的元素的值,其实都修改了“那些数组”的元素的值,所以原数组和新数组的元素值都一样了。
OK,就是这样。
不明白可以看看这个例子:
结果:
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中被访问了。
如果是复制一个一位数组,那么改变复制后的数组并不影响原数组。但是如果复制一个二维数组,那么改变其中任何一个数组,那么另一个的值也发生了变化。开始不是很明白,后来上网查了查资料,理解了其中奥妙。
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】Map.Entry 类使用简介
2012-05-10 11:12 521本文转自:http://www.cnblogs.com/guo ... -
【J2SE】Static Nested Class、Inner Class、Anonymous Inner Class
2012-05-05 11:58 0本文转自:http://blog.csdn.net/welco ... -
【J2SE】Anonymous Inner Class (匿名内部类)
2012-05-05 11:56 0本文转自:http://www.iteye ... -
【J2SE】生成者、消费者问题
2012-05-05 11:04 839本文转自:《Java JDK 实例宝典》 解决生产者消费者问 ... -
【J2SE】Java 运行时异常
2012-05-05 10:39 0本文转自:http://amyer.ite ... -
【J2SE】再谈线程:生产者与消费者
2012-05-04 23:36 0本文转自:http://www.blogjava.net/li ... -
【J2SE】Java线程:并发协作-生产者消费者模型
2012-05-04 23:34 0本文转自:http://lavasoft.blog.51cto ... -
【J2SE】线程7种状态的相互转换
2012-05-04 22:48 686本文转自:http://www.blogj ... -
【J2SE】详解java类的生命周期
2012-05-12 21:23 685本文转自:http://www.2cto.com/kf/20 ... -
Java文件操作大全
2012-05-02 13:29 0本文转自:http://www.blog ... -
【基础】Java Annotation详解
2012-05-02 11:50 0本文转自:http://www.blogjava.net/c ... -
【J2SE】Java JDBC数据库连接池总结
2012-05-03 23:21 901本文转自:http://www.blogj ... -
【基础】JAVA中String与StringBuffer的区别
2012-05-01 20:28 0String和StringBuffer的区别,网上资料可以说是 ... -
【J2SE】Java常见异常小结
2012-05-12 21:22 831本文重在Java中异常机制 ... -
【基础】Java异常处理及异常机制介绍
2012-05-01 19:54 0当出现程序无法控制的外部环境问题(用户提供的文件不存在,文件内 ... -
【基础】Java中finalize()
2012-05-01 19:39 0垃圾回收器要回收对象的时候,首先要调用这个类的finalize ... -
【基础】finally的一些测试
2012-05-01 16:37 0finally是在执行returen的中间执行。 pac ... -
【J2SE】Java之Path、CLASSPATH的概念解析
2012-05-03 23:17 801本文转自:http://blog.sin ... -
【J2SE】Java 反射机制简述
2012-05-03 23:19 674本文转自:http://zk1878.iteye.com/b ... -
【J2SE】Java中生成对象的4方式
2012-05-01 12:46 0本文转自:http://blog.sina.com.cn/s/ ...
相关推荐
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 官方帮助文档,chm格式,使用更加方便
J2SE6.0.chm api
“j2se6.chm”文件是这个压缩包中的核心资源,它包含了完整的J2SE6 API文档,是开发者查询类库、方法和接口的宝典。通过这个文件,开发者可以快速查找类的详细信息,了解其构造函数、方法、常量等,这对于编写Java...
自1995年发布JDK 1.0以来,Java经历了多个版本的发展,包括JDK 1.1、JDK 1.2(将Java更名为Java 2),并将其分为J2SE(Java标准版)、J2EE(Java企业版)、J2ME(Java微型版)。2005年Java迎来了十周年,Java 2平台...
Java 2 Standard Edition (J2SE) 是 Java 平台的核心部分,主要用于开发桌面应用程序。这个压缩包"j2se代码.zip"显然包含了与 Java 编程相关的源代码,非常适合那些刚开始学习 Java 的初学者。这里我们将深入探讨 ...
j2se6.part3.chm 英文版的非中文版
j2se6.part1,chm格式,英文版的
标题“j2se6.rar_Looking Up”和描述“api for looking up java codes”暗示了这个压缩包可能包含了与Java SE 6相关的API文档,特别是关于查找或搜索Java代码方面的内容。Java SE(标准版)是Java平台的核心部分,...
com.google.zxing.client.j2se.BufferedImageLuminanceSource和com.google.zxing.client.j2se.MatrixToImageWriter,亲测可用
这个压缩包"j2se.rar_j2EE api_j2se_j2se.c"显然包含了与 J2EE 和 Java Standard Edition (J2SE) 相关的资源,尤其是 J2EE 的API文档以及可能的 J2SE 相关代码示例。 J2SE 是 Java 平台的核心部分,它为桌面应用和...
标题中的"zxing-j2se01.7.jar"是ZXing Java版本的一个特定发行版,版本号为1.7。这个JAR文件包含了ZXing库的所有Java类和资源,可供Java开发者在桌面应用或服务器端项目中使用,实现条形码的读取和生成。如果你在...
6. **变量推断(varargs)**:允许方法参数接受可变数量的参数,语法上用三个点(...)表示,简化了方法调用。 7. **静态导入**:允许一次性导入某个包中的所有静态成员,避免了多次import语句,使代码更易读。 8....
标题中的"j2se6.chm.zip"表明这是一个关于Java 2 Standard Edition (J2SE) 6的压缩包文件,通常包含一个.chm(Microsoft Compiled HTML Help)格式的文档,这种格式常用于技术手册和指南。CHM文件集成了HTML页面,...
Java Standard Edition(简称J2SE)是Java平台的核心部分,为开发桌面应用程序和服务器应用程序提供了基础框架。这个压缩包文件“J2SE课程.rar”显然包含了一套完整的J2SE学习资源,旨在帮助初学者或者有志于深入...
[Java参考文档].J2SE6.0_CN.CHM,由于文件过大,所以划分了两个rar文件
因为这是java的总结需要有点基础的看,要不看不懂,不需要大家太多积分,如果感觉哪写的不对留言哈
自学java必备资源,高级教师推荐,欢迎下载!
这些API文档是Java开发者的重要参考资料,通过查阅它们,开发者可以了解每个类、接口和方法的详细功能、使用示例和注意事项。无论是初学者还是经验丰富的开发者,都应该熟悉并熟练运用这些API来提高编程效率和代码...