1、前述
java里面,数组的“扩容”与“拷贝”,借助“拷贝”实现“动态数组”
java里面的数组 int arr[]= new int[10]; arr在栈上 new出来的东西在堆上
所谓的数组的扩容,其实是对象所指向的内存发生了变化,导致数组“看起来长度变化”,并不是真正意义上的“动态数组”
拷贝前后,内存分离 深拷贝
反之,浅拷贝
2、实现
1、new一个新array
//way 1 new一个新array
int arr[] = new int[]{1,2,3,4,5,6,7,8,9,10};
int brr [] = new int[arr.length*2];
for(int i = 0;i<arr.length;i++){
brr[i] = arr[i];
}
arr = brr;
System.out.println("brr = arr"+Arrays.toString(arr));
if (arr==brr)
System.out.println("共用地址");
else
System.out.println("地址不同");
2 Object类的 clone方法 克隆,并不会改变长度
//way2 clone方法 克隆,并不会改变长度
int crr[] = new int[]{1,2,3,4,5,6,7,8,9,10};
int drr[] =crr.clone();
System.out.println("clone"+Arrays.toString(drr));
if (crr==drr)
System.out.println("共用地址");
else
System.out.println("地址不同");
//Object 类的clone方法 该方法是类 Object 中的方法,可以创建一个有单独内存空间的对像。故而是地址不同的
3、Arrays.copyOf()方法 底层实现是System.arrayCopy()
int err[]= new int[]{1,2,3,4,5,6,7,8,9,10};
int frr[]=Arrays.copyOf(err,err.length*2);
System.out.println("Arrays.copyOf"+Arrays.toString(frr));
if (err==frr)
System.out.println("共用地址");
else
System.out.println("地址不同");
/* Arrays.copyOf()底层实现,是 System.ArrayCopy()方法
//其机制是先new一个newLength的copy数组,借助System.ArrayCopy()把老数组内容拷贝到新数组,最后返回新数组
//所以,是new了一块地址 当然内存是不同的
源码实现
copyOf(int[] original, int newLength) {
int[] copy = new int[newLength];
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
* */
4、System.ArrayCopy() native方法 ,看不了实现
int grr[] = new int[]{1,2,3,4,5,6,7,8,9,10};
int hrr[] = new int[10];
//方法的src dest数组必须非空 必须声明空间 不然报错
System.arraycopy(grr,0,hrr,0,grr.length);
System.out.println("System.Arraycopy"+Arrays.toString(hrr));
if (grr==hrr)
System.out.println("共用地址");
else
System.out.println("地址不同");
//System.ArrayCopy() 是native方法,无法查看其源码
5、浅拷贝的一种实现
int irr[] = new int[]{1,2,3,4,5,6,7,8,9,10};
int jrr[] = irr;
System.out.println(" int jrr[] = irr;"+Arrays.toString(hrr));
if (irr==jrr)
System.out.println("共用地址");
else
System.out.println("地址不同");
//其实这和way1是一样的,way1是new了块新内存,但原来的数组指向了新的内存 内存是有共用的
//这块,是新数组没有new出地址,直接指向老数组的地址
上面几个方法,对于一维数组是深度拷贝,即内存分离。但对于二维数组或n维, 可以理解为定义了一个二维数组,内存在堆中开辟,其中一维是共享地址的,另一维是内存独立的,属于浅拷贝。 可以通过循环,实现内存分离的深度拷贝