Java高级篇-6-数组拷贝方法
来源:互联网 发布:杀人软件 编辑:程序博客网 时间:2024/05/29 18:23
前面我们介绍了Array和Arrays类几个常用的方法,没有提到对象clone()方法和Arrays.copyOf(),关于拷贝,放到这篇来讨论。拷贝或者复制,一般是对象的引用的操作,有三种方式来实现:直接赋值,浅拷贝,深拷贝。下面我们用代码来理解这三种情况。面试中经常拿数组的几种拷贝方法,来考察你对浅拷贝和深拷贝的理解。特别是直接赋值和对象clone这两个方法。
1.直接赋值
运行结果:
运行结果:
运行结果:
上面我们数组变成了String类型,里面的元素值也是String,我们知道String是一个类,不属于基本数据类型,所以,这里是引用类型。因为数组索引为2的元素是一个String类型,数组a和数组b的索引为2的元素都指向同一个索引,当修改a中引用指向的值是WuHan,数组b由于引用没有发生改变,所以值也没有跟着变化,还是指向了HeBei。clone()比较特殊,对于对象而言,它是深拷贝,但是对于数组而言,它是浅拷贝,因为数组每个元素如果是引用类型的话,数组本来存储的就是对象的引用。
2.4 Arrays.copyOf()实现浅拷贝
关于浅拷贝,推荐2.3或者2.4的方法,2.3执行速度更快。我分别测试了下,System.arraycopy显示0毫秒,而Arrays.copyOf()输出1毫秒。其实Arrays.copyOf()内部实现是调用了System.arraycopy方法。
1.直接赋值
直接赋值很简单,例如Int a = 10, 第二行b=a,这里直接把a赋值给了b。这个时候,a和b是相等,内存地址相同,值也相等。我们用一个int基本类型的数组来举例。
package demo3;import java.lang.reflect.Array;import java.util.Arrays;/** * create by Anthony on 2017/10/29 */public class ArraysDemo { public static void main(String args[]){ int[] a = {40, 20, 50, 10, 60, 30}; int[] b = a; System.out.println(a == b); //证明a发生变化,b会不会也变化 Array.set(a,2,100); System.out.println("a "+Arrays.toString(a)); System.out.println("b "+Arrays.toString(b)); }}
运行结果:
truea [40, 20, 100, 10, 60, 30]b [40, 20, 100, 10, 60, 30]从运行结果看出:数组a和数组b确实是完全相等,值相等,内存地址也相同。也就是说数组a和数组b实际上都是指向了同一个对象。上面修改了数组a的值,直接赋值得到的数组b的值也跟随变化。
2.浅拷贝
上面直接赋值的结果就是数组a和数组b完全相同,如果修改a,b也会跟着修改。实际上,我们可能不希望这样,我们希望复制过来的b和a进行区分,两者保持独立,不能互相影响。实现这个功能有一个方法就是Object的clone()方法。Object是Java的对象,所有类的父类。这个克隆实现的功能是:创建一个新对象,然后将当前对象的非静态字段复制到该新对象,如果字段是值类型的,那么对该字段执行复制;如果该字段是引用类型的话,则复制引用但不复制引用的对象。因此,原始对象及其副本引用同一个对象。
2.1 我们先看看如果字段是值类型,也就是八大基本数据类型的情况
package demo3;import java.lang.reflect.Array;import java.util.Arrays;/** * create by Anthony on 2017/10/29 */public class ArraysDemo { public static void main(String args[]){ int[] a = {40, 20, 50, 10, 60, 30}; int[] b = a.clone(); System.out.println(a == b); //证明a发生变化,b会不会也变化 Array.set(a,2,100); System.out.println("a "+Arrays.toString(a)); System.out.println("b "+Arrays.toString(b)); }}
运行结果:
falsea [40, 20, 100, 10, 60, 30]b [40, 20, 50, 10, 60, 30]上面可以看出,数组a是Int类型,也就是一个基本数据类型的数组,所以直接进行了值的复制。复制之后,数组b和数组a是内存地址不相等。如果我们操作数组a,数组b是不会受到影响。
2.2 看看如果是引用型的数组
package demo3;import java.lang.reflect.Array;import java.util.Arrays;/** * create by Anthony on 2017/10/29 */public class ArraysDemo { public static void main(String args[]){ String[] a = {"Beijing", "ShangHai", "HeBei", "GuangZhou", "XiAn"}; String[] b = a.clone(); System.out.println(a == b); //证明a发生变化,b会不会也变化 Array.set(a,2,"WuHan"); System.out.println("a "+Arrays.toString(a)); System.out.println("b "+Arrays.toString(b)); }}
运行结果:
falsea [Beijing, ShangHai, WuHan, GuangZhou, XiAn]b [Beijing, ShangHai, HeBei, GuangZhou, XiAn]
上面我们数组变成了String类型,里面的元素值也是String,我们知道String是一个类,不属于基本数据类型,所以,这里是引用类型。因为数组索引为2的元素是一个String类型,数组a和数组b的索引为2的元素都指向同一个索引,当修改a中引用指向的值是WuHan,数组b由于引用没有发生改变,所以值也没有跟着变化,还是指向了HeBei。clone()比较特殊,对于对象而言,它是深拷贝,但是对于数组而言,它是浅拷贝,因为数组每个元素如果是引用类型的话,数组本来存储的就是对象的引用。
2.3 System.arrayCopy()实现浅拷贝
package demo3;import java.lang.reflect.Array;import java.util.Arrays;/** * create by Anthony on 2017/10/29 */public class ArraysDemo { public static void main(String args[]){ String[] a = {"Beijing", "ShangHai", "HeBei", "GuangZhou", "XiAn"}; String[] b = new String[a.length]; System.arraycopy(a, 0, b, 0, a.length); System.out.println(a == b); //证明a发生变化,b会不会也变化 Array.set(a,2,"WuHan"); System.out.println("a "+Arrays.toString(a)); System.out.println("b "+Arrays.toString(b)); }}
2.4 Arrays.copyOf()实现浅拷贝
package demo3;import java.lang.reflect.Array;import java.util.Arrays;/** * create by Anthony on 2017/10/29 */public class ArraysDemo { public static void main(String args[]){ String[] a = {"Beijing", "ShangHai", "HeBei", "GuangZhou", "XiAn"}; String[] b = Arrays.copyOf(a, a.length); System.out.println(a == b); //证明a发生变化,b会不会也变化 Array.set(a,2,"WuHan"); System.out.println("a "+Arrays.toString(a)); System.out.println("b "+Arrays.toString(b)); }}
关于浅拷贝,推荐2.3或者2.4的方法,2.3执行速度更快。我分别测试了下,System.arraycopy显示0毫秒,而Arrays.copyOf()输出1毫秒。其实Arrays.copyOf()内部实现是调用了System.arraycopy方法。
3.深拷贝
深拷贝,就是说创建一个新对象,然后将当前对象的非静态字段复制到该新对象,无论该字段是值类型的还是引用类型,都进行复制。由于数组元素本来就存储对象的引用,所以,这里无法举例来实现数组的深拷贝。以后在类和对象的知识来介绍对象的深拷贝。
阅读全文
1 0
- Java高级篇-6-数组拷贝方法
- Java数组拷贝方法arraycopy()
- 【Java】 数组拷贝的通用方法
- Java数组拷贝的四种方法
- java拷贝数组(深拷贝)
- Java 数组 的 拷贝
- java中数组拷贝
- java中拷贝数组
- Java 数组的拷贝
- java中的数组拷贝
- JAVA二维数组拷贝
- Java 数组的拷贝
- Java数组拷贝
- JAVA 数组拷贝
- Java数组拷贝
- Java拷贝数组
- Java 数组拷贝
- Java核心技术--数组拷贝
- 矩形滑雪场(深度搜索)
- Git系列-环境搭建
- 开发第一个SPringMVC的程序
- tensorflow实现softmax regression识别手写数字
- Python系列-比较两个数的大小
- Java高级篇-6-数组拷贝方法
- get和post请求区别
- [贪心+堆+链表] 51Nod1053 最大M子段和 V2
- [练习][洛谷2700]Kruskal 逐个击破
- Leetcode: 322. Coin Change(Week8, Medium)
- listview and arrayadapter
- 【weekly-sharing】BM算法(Boyer-Moore算法)学习记录
- “千里眼”“顺风耳” 铁路依靠科技创新实现安全管理现代化
- How to Cast Your Android Screen onto Your Linux Desktop