- 浏览: 394749 次
- 性别:
- 来自: 大连
文章分类
最新评论
-
surpassno:
南冠楚囚 写道如果是复制一个一位数组,那么改变复制后的数组并不 ...
java的system.arraycopy()方法 -
南冠楚囚:
如果是复制一个一位数组,那么改变复制后的数组并不影响原数组。你 ...
java的system.arraycopy()方法 -
wxq5513866:
有密码,大家不要下载了,下载也解压不了,别上当了
android中调用webservice -
wxq5513866:
happyhan 写道还要密码啊 能否告知密码
android中调用webservice -
happyhan:
还要密码啊 能否告知密码
android中调用webservice
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
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
你用的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
你用的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
发表评论
-
jmx介绍
2012-05-18 15:21 1324"JMX(Java Management Exten ... -
RMI介绍
2012-05-18 09:55 1058Java RMI (Remote Method Invocat ... -
java多线程文件下载
2012-03-08 20:03 24711、DownloadManager类 import java. ... -
java异常处理
2011-11-30 15:27 987public class test { /** ... -
快排和插入排序
2011-10-20 17:08 1147public class CombineQuickSortIn ... -
java NIO
2011-10-09 19:22 1451一、NIO的出现 NIO是JDK1.4里面才出 ... -
java 远程通信协议
2011-10-09 16:55 1584Java 远程通讯可选技术及原理 在分布式服务框架中,一个最基 ... -
system.exit
2011-09-29 17:00 1020System.exit()用来结束当前运行的java虚拟机,参 ... -
java 文件读取方法
2011-09-27 14:50 12361、按字节读取文件内容 2、按字符读取文件内容 3、按行读取文 ... -
timestamp时间戳
2011-09-05 09:51 1231timestamp是一种时间类型 精度很高,比datetim ... -
java 动态代理类的实现,原理及应用
2011-09-03 11:02 2201在目前的Java开发包中包含了对动态代理的支持,但是其实现只支 ... -
java annotation 介绍
2011-09-02 11:03 956元数据的作用 如果要 ... -
java 反射
2011-08-20 11:27 798JAVA语言中的反射机制: 在Java 运行时 环境中 ... -
junit使用
2011-08-05 16:41 1168测试分类:白箱测试、黑箱测试、单元测试、集成测试、功能测试.. ... -
ThreadLocal 知识
2011-08-05 13:58 858ThreadLocal是什么 早在JD ... -
httpclient 介绍
2011-07-28 09:33 10631.HttpClient简介 HttpCl ... -
java解析xml的四种方法
2011-07-13 22:52 14651. DOM(Document Object Model) ... -
xml字符串转化为规则格式的xml字符串
2011-07-13 18:53 1394import java.io.ByteAr ... -
java中的参数传递
2011-07-13 10:48 986面试题:当一个对象被当 ... -
StringUtils的实用方法
2011-07-13 10:16 1702tringUtils 方法的操作对象是 java.lang. ...
相关推荐
在Java编程语言中,`System.arraycopy()`是一个非常实用且高效的方法,用于在数组之间复制元素。此方法属于`java.lang.System`类,并且是一个静态方法,这意味着可以直接通过`System`类名调用它,而无需创建`System`...
`System.arraycopy` 和 `Arrays.copyOf` 都是Java中用于复制数组的方法,但它们在使用和处理异常情况上有所不同。这两个方法在处理数组复制时,提供了便利和效率,但各有其适用场景。 `System.arraycopy` 是一个...
在Java中有多种方式可以实现数组合并,本文将介绍两种常见的实现方式,即使用System.arraycopy()方法和ArrayUtils.addAll()方法。 1. System.arraycopy()方法 System.arraycopy()方法是Java提供的一种本地方法,...
本篇文章将介绍两种方法来合并两个数组,一种是使用Java内置的`System.arraycopy()`函数,另一种是不使用预定义函数,而是通过手动遍历来实现。 首先,让我们详细讨论使用`System.arraycopy()`的方法。这个方法是从...
在第三个方法中,我们使用了 System.arraycopy 方法来实现数组合并。我们首先创建了一个新的字符串数组 c,然后使用 System.arraycopy 方法将数组 a 和 b 的元素复制到数组 c 中。 代码实现: ```java public ...
这三种方法分别是:使用循环手动填充新数组、利用`List`集合进行合并再转换为数组以及直接使用`System.arraycopy()`方法。此外,还将涉及如何合并不同类型的数组,如字符数组与整型数组。 ### 方法一:使用循环合并...
需要注意的是,在 add(int index, E element) 方法中,我们使用 System.arraycopy 方法来复制数组元素,这是一个 native 方法,它的实现是基于 C++ 语言的。很多人认为 System.arraycopy 方法是调用底层的 memcpy ...
数组倒置也可以使用Java的`System.arraycopy`方法来实现,这种方法更加简洁高效: ```java public class C { public static void main(String[] args) { int[] array = {1, 2, 3, 4, 5}; reverseArray(array); ...
数组元素的复制通常有两种方式:使用循环进行逐个元素的复制,以及使用Java提供的`System.arraycopy()`方法。 首先,我们来探讨一下使用循环复制数组元素的方法。例如,当我们有一个已经初始化的数组`a`,我们想要...
另一种方法是使用Java的`System.arraycopy()`函数,它可以高效地复制数组的一部分。在数组倒置的情况下,我们可以先创建一个临时数组,然后使用`arraycopy()`将原数组的后半部分复制到临时数组,再将原数组的前半...
### Java反射操作父类所有属性和方法 #### 一、引言 在Java编程语言中,反射(Reflection)是一项强大的特性,它允许程序在运行时动态地获取类的信息,并能够直接操作这些信息。通过反射,我们可以获取类的字段、...
赋值操作(如`bb = aa`)只会让两个数组引用指向同一块内存,而`System.arraycopy()`方法则会真正复制数组的内容到另一块内存。 在处理大量数据时,Java集合框架中的`ArrayList`和`LinkedList`等集合类通常比数组更...
总结来说,Java中合并两个`byte`数组可以通过创建新的数组并使用`System.arraycopy()`方法来实现。如果需要进一步处理合并后的数组,如反转或加密,可以分别使用自定义函数或Java内置的加密库。这些操作在处理二进制...
Java中的`java.lang.System`类是Java核心库中不可或缺的一部分,它是系统级操作的主要入口点。这个类提供了很多静态字段和...理解并熟练使用`System`类的各种方法,可以帮助开发者更好地操控Java程序与系统资源的交互。
Java提供了System类的arraycopy()方法,它是进行数组复制的最直接和高效的方式。该方法接受五个参数:源数组、源数组起始位置、目标数组、目标数组起始位置和复制的元素数量。例如: ```java int[] srcArray = {1...
`System.arraycopy()`是Java提供的一个高效的方法,用于复制数组。相比使用循环逐个元素复制,`System.arraycopy()`在底层实现上更优化,能提供更好的性能。例如,如果你需要复制一个整型数组,避免使用for循环,...
在Java数组复制方法中,效率最高的方法是System.arraycopy。 提到的Java代码中存在空指针异常的情况,但通过测试发现这段代码可以正常运行,因为Java的静态方法可以在类被加载的时候调用,即使它所属的对象是空...
这里提到了可以使用 `java.util.Arrays` 和 `java.util.Collections` 提供的方法来实现高效拷贝。下面详细介绍这两种方法: - **使用 `java.util.Arrays.copyOf()`:** `java.util.Arrays.copyOf()` 方法是拷贝...
* 在JAVA中,可以使用System.arraycopy()方法将一个数组的元素复制到另一个数组中。 * System.arraycopy()方法的参数包括源数组、源数组的起始索引、目标数组、目标数组的起始索引和要复制的元素个数。 例如,在...