详解Java数组的四种拷贝方式
目录
- 深拷贝与浅拷贝的区别
- 1.for循环进行拷贝
- 拷贝数值类型
- 拷贝引用类型
- 2.copyof/copyOfRange
- 拷贝数值类型
- 拷贝引用类型
- 3.arraycopy
- 拷贝数值类型
- 拷贝引用类型
- 4.clone
- 拷贝数值类型
- 拷贝引用类型
- 5.总结
深拷贝与浅拷贝的区别 假设现在有原数组A以及拷贝后的数组B,若是改变A中的某一个值,B数组随之相应的发生变化的拷贝方式称为浅拷贝,反之B数组不受影响,则称为深拷贝;
简单总结一下两者的概念:
深拷贝:拷贝后,修改原数组,不会影响到新数组;
浅拷贝:拷贝后,修改原数组,新数组也会相应的发生改变;
1. for循环进行拷贝
拷贝数值类型
当数组中存放的元素为基本数据类型时,此时发生的是深拷贝;
//1. for循环拷贝(拷贝数值类型) ---深拷贝public static void main(String[] args) {int[] A = {1,2,3,4,5}; int[] B = new int[A.length]; for (int i = 0; i < A.length; i++) {B[i] = A[i]; }System.out.println("A : " + Arrays.toString(A)); //A : [1, 2, 3, 4, 5]System.out.println("B : " + Arrays.toString(B)); //B : [1, 2, 3, 4, 5]System.out.println("===========修改后==========="); A[0] = 100; System.out.println("A : " + Arrays.toString(A)); //A : [100, 2, 3, 4, 5]System.out.println("B : " + Arrays.toString(B)); //B : [1, 2, 3, 4, 5]}//打印对象数组的方法public static void show(Num[] arrays) {for (int i = 0; i < arrays.length; i++) {System.out.print(arrays[i].getVal() + " "); }System.out.println(); }class Num{public int val = 0; public Num(int val) {this.val = val; }public int getVal() {return val; }public void setVal(int val) {this.val = val; }}
拷贝引用类型
当数组中存放的元素为引用数据类型时,此时发生的是浅拷贝;
//1. for循环拷贝(拷贝引用数据类型) ---浅拷贝public static void main(String[] args) {Num[] A = new Num[4]; A[0] = new Num(1); A[1] = new Num(2); A[2] = new Num(3); A[3] = new Num(4); Num[] B = new Num[4]; for (int i = 0; i < A.length; i++) {B[i] = A[i]; }show(A); //1 2 3 4 show(B); //1 2 3 4 System.out.println("===========修改后==========="); A[0].setVal(100); show(A); //100 2 3 4show(B); //100 2 3 4}
2. copyof / copyOfRange 拷贝数值类型
当数组中存放的元素为基本数据类型时,此时发生的是深拷贝;
Arrays.copy(原数组,自定义新数组长度);
Arrays.copyOfRange(原数组,from,to);
注意拷贝截取的范围是左闭右开的[from,to)
//2. copy / copyOfRange(拷贝数值类型) ---深拷贝public static void main(String[] args) {int[] A = {1,2,3,4,5}; int[] B = Arrays.copyOf(A,A.length); int[] C = Arrays.copyOfRange(A,1,3); System.out.println("A : " + Arrays.toString(A)); //A : [1, 2, 3, 4, 5]System.out.println("B : " + Arrays.toString(B)); //B : [1, 2, 3, 4, 5]System.out.println("C : " + Arrays.toString(C)); //C : [2, 3]System.out.println("===========修改后==========="); A[0] = 100; System.out.println("A : " + Arrays.toString(A)); //A : [100, 2, 3, 4, 5]System.out.println("B : " + Arrays.toString(B)); //B : [1, 2, 3, 4, 5]System.out.println("C : " + Arrays.toString(C)); //C : [2, 3]}
拷贝引用类型
当数组中存放的元素为类的对象时,此时发生的是浅拷贝;
//2. copy / copyOfRange(拷贝引用类型) ---浅拷贝public static void main(String[] args) {Num[] A = new Num[4]; A[0] = new Num(1); A[1] = new Num(2); A[2] = new Num(3); A[3] = new Num(4); Num[] B = Arrays.copyOf(A,A.length); show(A); //1 2 3 4show(B); //1 2 3 4System.out.println("===========修改后==========="); A[0].setVal(100); show(A); //100 2 3 4show(B); //100 2 3 4}class Num{public int val = 0; public Num(int val) {this.val = val; }public int getVal() {return val; }public void setVal(int val) {this.val = val; }}
3. arraycopy 拷贝数值类型
当数组中存放的元素为基本数据类型时,此时发生的是深拷贝;
System.arraycopy(src, srcPos dest, destPos, length);
其中各个参数分别表示 如下:
- src :源数组
- srcPos:源数组要复制的起始位置
- dest:目标数组
- destPos:目标数组复制的起始位置
- length:复制的长度
//3. arraycopy(拷贝数值类型) ---深拷贝public static void main(String[] args) {int[] A = {1,2,3,4,5}; int[] B = new int[A.length]; //System.arraycopy(A,0,B,0,A.length); System.arraycopy(A,1,B,2,2); System.out.println("A : " + Arrays.toString(A)); //A : [1, 2, 3, 4, 5]System.out.println("B : " + Arrays.toString(B)); //B : [0, 0, 2, 3, 0]System.out.println("===========修改后==========="); A[0] = 100; System.out.println("A : " + Arrays.toString(A)); //A : [100, 2, 3, 4, 5]System.out.println("B : " + Arrays.toString(B)); //B : [0, 0, 2, 3, 0]}
拷贝引用类型
当数组中存放的元素为类的对象时,此时发生的是浅拷贝;
//3. arraycopy(拷贝引用类型) ---浅拷贝public static void main(String[] args) {Num[] A = new Num[4]; A[0] = new Num(1); A[1] = new Num(2); A[2] = new Num(3); A[3] = new Num(4); Num[] B = new Num[4]; System.arraycopy(A,0,B,0,A.length); show(A); //1 2 3 4show(B); //1 2 3 4System.out.println("===========修改后==========="); A[0].setVal(100); show(A); //100 2 3 4show(B); //100 2 3 4}class Num{public int val = 0; public Num(int val) {this.val = val; }public int getVal() {return val; }public void setVal(int val) {this.val = val; }}
4. clone 拷贝数值类型
当数组中存放的元素为基本数据类型时,此时发生的是深拷贝;
//4. clone(拷贝数值类型) ---深拷贝public static void main(String[] args) {int[] A = {1,2,3,4,5}; int[] B = A.clone(); System.out.println("A : " + Arrays.toString(A)); //A : [1, 2, 3, 4, 5]System.out.println("B : " + Arrays.toString(B)); //B : [1, 2, 3, 4, 5]System.out.println("===========修改后==========="); A[0] = 100; System.out.println("A : " + Arrays.toString(A)); //A : [100, 2, 3, 4, 5]System.out.println("B : " + Arrays.toString(B)); //B : [1, 2, 3, 4, 5]}
拷贝引用类型
当数组中存放的元素为类的对象时,此时发生的是浅拷贝;
//4. clone(拷贝引用类型) ---浅拷贝public static void main(String[] args) {Num[] A = new Num[4]; A[0] = new Num(1); A[1] = new Num(2); A[2] = new Num(3); A[3] = new Num(4); Num[] B = A.clone(); show(A); //1 2 3 4show(B); //1 2 3 4System.out.println("===========修改后==========="); A[0].setVal(100); show(A); //100 2 3 4show(B); //100 2 3 4}
5. 总结
拷贝方式 | 数值类型 | 引用类型 | 推荐使用 |
---|---|---|---|
for循环 | 深拷贝 | 浅拷贝 | |
copyof | 深拷贝 | 浅拷贝 | √ |
arraycopy | 深拷贝 | 浅拷贝 | √ |
clone | 深拷贝 | 浅拷贝 |
注意:本文中所有的引用数据类型都是以类的对象为例,使用的是对象数组,我们也知道引用类型包括类,接口,字符串等等。但是需要注意字符串是新的变量,所以如果是连个字符串数组进行拷贝,即使他们是引用类型,但是每次都会创建了一个字符串数组对象, 因此, 修改原数组, 不会影响到新数组,即深拷贝。
【详解Java数组的四种拷贝方式】以上就是详解Java数组的四种拷贝方式的详细内容,更多关于Java数组拷贝的资料请关注脚本之家其它相关文章!
推荐阅读
- JAVA中的|JAVA中的 map,list,set
- java|java 如何给对象中的包装类设置默认值
- C++|[C/C++]详解STL容器1--string的功能和模拟实现(深浅拷贝问题)
- 蓝桥杯真题(C/C++)|题目 1575: 递归倒置字符数组
- java中的List接口(ArrayList、Vector、LinkedList)
- mybatis介绍--基于个人学习JavaWeb的使用
- Spring源码之九finishRefresh详解
- 简单聊一聊Javascript中的模块化
- Java8中CompletableFuture的用法全解
- IDEA神器一键查看Java字节码及其他类信息插件