详解Java数组的四种拷贝方式

网友投稿 258 2022-08-26


详解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]

http:// 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 4

show(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 4

show(B); //1 2 3 4

System.out.println("===========修改后===========");

A[0].setVal(100);

show(A); //100 2 3 4

show(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:复制的长度

所以srcPos和destPos都为0,且length为源数组长度时,表示完完整整的拷贝过来了;那么截取范围拷贝也举个例子,下面的代码中srcPos = 1,destPos = 2,length = 2,表示从A数组下标为1的位置开始截取2个元素,放到B数组中下标为2的位置作为起始位置,再对比一下输出看看。

//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 4

show(B); //1 2 3 4

System.out.println("===========修改后===========");

A[0].setVal(100);

show(A); //100 2 3 4

show(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.toStrinKXWGbg(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 4

show(B); //1 2 3 4

System.out.KXWGbprintln("===========修改后===========");

A[0].setVal(100);

show(A); //100 2 3 4

show(B); //100 2 3 4

}

5. 总结

拷贝方式数值类型引用类型推荐使用for循环深拷贝浅拷贝 copyof深拷贝浅拷贝√arraycopy深拷贝浅拷贝√clone深拷贝浅拷贝

由于arraycopy底层是C++写的,所以速度快,更多的是使用这个方法。

注意:本文中所有的引用数据类型都是以类的对象为例,使用的是对象数组,我们也知道引用类型包括类,接口,字符串等等。但是需要注意字符串是新的变量,所以如果是连个字符串数组进行拷贝,即使他们是引用类型,但是每次都会创建了一个字符串数组对象, 因此, 修改原数组, 不会影响到新数组,即深拷贝。

以上就是详解java数组的四种拷贝方式的详细内容,更多关于Java数组拷贝的资料请关注我们其它相关文章!


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:ubuntu18 安装python3.8.tgzPython3.8tgz安装-Ubuntu文档类资源(ubuntu18内核版本)
下一篇:python基础学习笔记(十一)(Python百度文库)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~