java:数组拷贝与“扩容”

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维,
可以理解为定义了一个二维数组,内存在堆中开辟,其中一维是共享地址的,另一维是内存独立的,属于浅拷贝。
可以通过循环,实现内存分离的深度拷贝
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

约翰兰博之西安分博

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值