当前位置: 移动技术网 > IT编程>开发语言>Java > 大厂面试手撕源码之java数组拷贝

大厂面试手撕源码之java数组拷贝

2020年08月17日  | 移动技术网IT编程  | 我要评论
深拷贝与浅拷贝的关键之处在于是否分配了新的内存空间。1.使用for循环进行数组拷贝(深拷贝)int[] array=new int[] {1,2,3,4};int[] array1=new int[array.length];for(int i=0;i<array.length;i++) {array1[i]=array[i];}int[][] array2=new int[][] {{1,3,2},{1,4,5},{4,2,5}};int[][] array3=ne

深拷贝与浅拷贝的关键之处在于是否分配了新的内存空间。

1.使用for循环进行数组拷贝(深拷贝)

 int[] array=new int[] {1,2,3,4}; int[] array1=new int[array.length]; for(int i=0;i<array.length;i++) { array1[i]=array[i]; } int[][] array2=new int[][] {{1,3,2},{1,4,5},{4,2,5}}; int[][] array3=new int[array2.length][array2[0].length]; for(int i1=0;i1<array2.length;i1++) { for(int j=0;j<array2[i1].length;j++) { array3[i1][j]=array2[i1][j]; } } array3[0][0] = 11; //测试(如果修改array3的值,显然不会修改array2的值) System.out.println(Arrays.deepToString(array2)); System.out.println(Arrays.deepToString(array3)); 

其中Arrays.deepToString()用于打印二维数组。
Arrays.toString()打印一维数组。

2.使用Arrays.copyOf(),本质仍是调用System.arraycopy()(深拷贝

Arrays.copyOf()源码解读:

//非基本数据类型 public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) { @SuppressWarnings("unchecked") //返回值类型,如果返回的数组类型和原始数组一致,否则,通过反射机制创建一个新的类型的数组实例。 T[] copy = ((Object)newType == (Object)Object[].class) ? (T[]) new Object[newLength] : (T[]) Array.newInstance(newType.getComponentType(), newLength); System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength)); return copy; } //基本数据类型 public static int[] copyOf(int[] original, int newLength) {//original为原数组 int[] copy = new int[newLength];//分配新的堆内存空间 System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength));//调用System的arraycopy方法,其中参数: //1:Object src:这个代表源数组 //2:int srcPos:这个代表复制时要从源数组的什么位置开始 //3:Object dest:这个是目标数组,就是我们要把数组复制到这个数组 //4:int destPos:这个代表你要把要复制的内容从到目标数组的什么位置开始 //5:int length:这个就是源数组要把多长的长度复制到目标数组 return copy; } 

那么为什么要调用Math.min函数来获取目标数组的长度呢?
源码解释如下:
*Copies the specified array, truncating or padding with nulls (if necessary)
* so the copy has the specified length. For all indices that are
* valid in both the original array and the copy, the two arrays will
* contain identical values. For any indices that are valid in the
* copy but not the original, the copy will contain null.
* Such indices will exist if and only if the specified length
* is greater than that of the original array.
* The resulting array is of the class newType.

即:如果目标数组的长度(即给定的newLength)小于原始数组的长度,则截取原始数组中目标数组长度的部分,反之,则取目标数组的长度,没有值的地方以null填充

3.直接调用System.arraycopy()函数(深拷贝

源码如下:

public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length); 

解释见上!
关于native关键字的补充说明:使用native关键字说明这个方法是原生函数,也就是这个方法是用C/C++语言实现的,并且被编译成了DLL,由java去调用。 这些函数的实现体在DLL中,JDK的源代码中并不包含,你应该是看不到的。对于不同的平台它们也是不同的。这也是java的底层机制,实际上java就是在不同的平台上调用不同的native方法实现对操作系统的访问的。

4.使用Object的clone方法(深拷贝)

protected native Object clone() throws CloneNotSupportedException; 

clone方法是从Object类继承过来的,基本数据类型(int ,boolean,char,byte,short,float ,double,long)都可以直接使用clone方法进行克隆,注意String类型是因为其值不可变所以才可以使用。其他引用数据类型需要实现Cloneable接口,通过实现clone()方法进行深拷贝。

参考链接:
【1】JAVA基础随笔-SYSTEM.ARRAYCOPY()方法使用心得
【2】Java中数组的几种拷贝方式

本文地址:https://blog.csdn.net/qq_44713855/article/details/108031659

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网