Java的数组拷贝——四种方法
在java语言中 ,Java数组的复制操作可以分为深度复制和浅度复制。
简单来说深度复制,可以将对象的值和对象的内容复制;
浅复制是指对对象引用的复制。
第一种方法:clone() 方法
clone() 方法可以实现复制数组。该方法是类 Object 中的方法,可以创建一个有单独内存空间的对象。因为数组也是一个 Object 类,因此也可以使用数组对象的 clone() 方法来复制数组。
clone() 方法的返回值是 Object 类型,要使用强制类型转换为适当的类型。其语法形式比较简单:
array2 = array1.clone()
下面是一个测试实例:
import java.util.Scanner;
import java.util.Arrays;
public class text {
public static void main(String[] args) {
int[] array1 = new int[]{1,3,5,7,9};
int[] array2 = new int[array1.length];
//开一个与array1长度相同的数组array2
array2 = array1.clone();
System.out.println("array1 = "+Arrays.toString(array1));
System.out.println("array2 = "+Arrays.toString(array2));
System.out.println("===========================");
array2[0] = 100;
System.out.println("array1 = "+Arrays.toString(array1));
System.out.println("array2 = "+Arrays.toString(array2));
System.out.println("array1 的地址是: " + array1);
System.out.println("array2 的地址是: " + array2);
array2 = array1.clone();
System.out.println("array2 的地址是: " + array2);
}
}
输出如下:
到这里大家发现了什么???显然在上述图中出现了三种地址。
这三种地址的关系如下图所示:
可以看到,刚开始通过 int[] array2 = new int[array1.length] 语句申请的数组和array2 = array1.clone() 语句产生的数组并不是同一个数组。
小编上网查看clone()方法的源码,找到:总纲是Creates and returns a copy of this object. 意思是“ 创建并返回此对象的副本。”就可以理解为什么array2数组克隆前后指向不同的地址了!!!
对于clone()方法站在更高角度是这样解释的:
当对复制数组的某个元素进行改变时,被复制数组对应元素也随之改变,即对于引用数据类型来说clone()方法是浅拷贝。
通过内存分析可以很直观的看到,每个数组的元素分别指向同一个内存地址,当通过其中一个数组的某个元素对被指向地址的数值进行更改时,另一个数组相应的元素同样会发生改变。
第二种方法:System.arraycopy 方法(本地方法)
public static native void arraycopy(Object src, int srcPos, Object dest, int desPos, int length)
这句话是什么意思呢:(一共有五点)如下:
(原数组, 原数组的开始位置, 目标数组, 目标数组的开始位置, 拷贝个数)
import java.util.Scanner;
import java.util.Arrays;
public class text {
public static void main(String[] args) {
int[] a1 = {1, 2, 3, 4, 5};
int[] a2 = new int[10];
System.arraycopy(a1, 1, a2, 3, 3);
System.out.println(Arrays.toString(a1)); // [1, 2, 3, 4, 5]
System.out.println(Arrays.toString(a2)); // [0, 0, 0, 2, 3, 4, 0, 0, 0, 0]
}
}
看看上面的测试code,a1为原数组,a2为目标数组,System.arraycopy()这个方法,对a1的本身没有影响,emmmmmm
(原数组, 原数组的开始位置, 目标数组, 目标数组的开始位置, 拷贝个数)
(就上述code)从a1数组的第2个元素——“2”,开始对之后的元素,进行复制。(obj数组类似)
拷贝个数,控制从a1数组复制黏贴到a2数组上元素的个数。
第三中方法:Arrays.copyOf
同样看源码,它的实现还是基于System.arraycopy(),所以效率自然低于System.arraycpoy()
Arrays的copyOf()方法传回的数组是新的数组对象,改变传回数组中的元素值,不会影响原来的数组。copyOf()的第二个自变量指定要建立的新数组长度,如果新数组的长度超过原数组的长度,则保留数组默认值,如下:
import java.util.Arrays;
public class text {
public static void main(String[] args) {
int[] a1 = {1, 2, 3, 4, 5}; //初始化
int[] a2 = Arrays.copyOf(a1, 5);
int[] a3 = Arrays.copyOf(a1, 10);
for(int i = 0; i < a2.length; i++)
System.out.print(a2[i] + " ");
System.out.println();
for(int i = 0; i < a3.length; i++)
System.out.print(a3[i] + " ");
}
}
/**1 2 3 4 5
1 2 3 4 5 0 0 0 0 0 */
第四种方法:Arrays.copyOfRange
Arrays.copyOfRange底层其实也是用的System.arraycopy,只不过封装了一个方法
要使用这个方法,首先要import java.util.*;
Arrays.copyOfRange(T[ ] original,int from,int to)
将一个原始的数组original,从小标from开始复制,复制到小标to,生成一个新的数组。
注意这里包括下标from,不包括上标to。
这个方法在一些处理数组的编程题里很好用,效率和clone基本一致,比利用循环复制数组效率要高得多。
import java.util.Arrays;
public class text {
public static void main(String[] args) {
int[] a= {1,2,3,4,5,6,7,8,9,10};
int[] b=new int[8];
b=Arrays.copyOfRange(a, 2, 10);
System.out.print(Arrays.toString(b));
}
}
//[3, 4, 5, 6, 7, 8, 9, 10]
显然,方法中的copyOfRange(a,2,10),分别指数组a,a的第3个元素,a的第10个元素。
希望对大家有所帮助,谢谢!!!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)