Java—数组的Arrays工具类及拷贝方式

一、Arrays工具类

Arrays工具类源码在java.util包里,提供的常用方法有:

  • Arrays.sort 按升序进行数组排序(全部/部分)

  • Arrays.binarySearch 二分搜索法搜索指定类型的数组,以查找指定的键值

  • Arrays.equals 判断两个数组是否相等,返回结果为boolean类型

  • Arrays.fill 填充数组(全部/部分)

  • Arrays.toString / deepToString 将一维/多维以字符串形式输出

  • Arrays.copyOf 复制数组

  • Arrays.copyOfRange 复制指定范围的数组

二、数组拷贝方式的分类

  • for
  • clone
  • System.arrayCopy()
  • Arrays.copyOf()

1、for语句拷贝数组

定义两个数组,第二个数组的长度等于第一个数组,用for循环,从0号下标开始,把第一个数组的值依次赋给第二个数组的同号下标。
基本类型的拷贝:

     public static void main(String[] args) {
                int[] array = {1,2,3,4,5};
                int[] array2 = new int[array.length];
                for (int i = 0; i < array.length; i++) {
                    array2[i] = array[i];
                }
                System.out.println(Arrays.toString(array));  //原数组
                System.out.println(Arrays.toString(array2));  //拷贝后的数组

                array2[0] = 100; //修改数组0号下标的值

                System.out.println(Arrays.toString(array)); //修改前的数组
                System.out.println(Arrays.toString(array2)); //修改后的数组
            }
        }

执行结果:
在这里插入图片描述

引用类型的拷贝:

class TestArray {
    private int val = 10;
    public int getVal() {   //获得值
        return val;
    }
    public void setVal(int val) { //修改值
        this.val = val;
    }
        }
    public class forcopy {

            public static void main(String[] args) {
                TestArray[] testArrays = new TestArray[3];  //新建一个长度为3的数组testArrays
                testArrays[0] = new TestArray();  
                testArrays[1] = new TestArray();
                testArrays[2] = new TestArray();

                TestArray[] testArrays2 = new TestArray[3];//新建一个长度为3的数组testArray2

                for (int i = 0; i < testArrays.length; i++) {
                    testArrays2[i] = testArrays[i];   //用for语句拷贝数组
                }

                System.out.println("=====拷贝后======");
                for (int i = 0; i < testArrays.length; i++) {
                    System.out.print(testArrays[i].getVal() + " ");   //打印原数组
                }
                System.out.println();
                for (int i = 0; i < testArrays2.length; i++) {
                    System.out.print(testArrays2[i].getVal()+ " "); //打印拷贝后的数组
                }
                System.out.println();
                System.out.println("======修改0号下标的值后======");

                testArrays2[0].setVal(10000);   //把克隆后数组0号下标的值改为10000

                for (int i = 0; i < testArrays.length; i++) {
                    System.out.print(testArrays[i].getVal()+ " ");  //打印原数组
                }
                System.out.println();
                for (int i = 0; i < testArrays2.length; i++) {
                    System.out.print(testArrays2[i].getVal()+ " ");  //打印修改后的数组
                }
            }
}

执行结果:
在这里插入图片描述
由上面两个代码的执行结果不难看出,用for语句拷贝数组:

  • 如果数组是简单类型,在修改拷贝后数组0号下标的值的时候,原数组的值不会改变
  • 如果数组是引用类型(对象),在修改拷贝后数组0号下标的值的时候,原数组的值会改变
    原因:
    引用类型是地址,在修改的时候,引用类型地址的值会被改变,例如0号下标克隆之前的地址为100,克隆之后的地址也指向100,在修改克隆之后0号下标的值的时候,指向地址100的值也会被修改,所以原数组地址为100的值也会随之而改变。此时克隆前和克隆后两个引用类型同时指向同一个内存。
    这里就要引两个概念,深拷贝和浅拷贝
  • 深拷贝
  • 浅拷贝:两个引用同时指向栈中的同一块内存
    所以for是浅拷贝

2、clone方法拷贝数组

clone方法拷贝数组会产生新的对象
例:int [] a = {2,4,2,3,5};//定义数组a
int [] b = a.clone(); //定义数组b,把clone a后的数组存入b
源码:
在这里插入图片描述
凡是看到源码中有native的方法,底层都是用c/c++语言编写的,它的优点是:快!
简单类型的拷贝:

   public static void main(String[] args) {
            int[] array = {1,2,3,4,5};
            int[] array2 = array.clone();
            System.out.println(Arrays.toString(array));
            System.out.println(Arrays.toString(array2));
            array2[0] = 99;
            System.out.println(Arrays.toString(array));
            System.out.println(Arrays.toString(array2));

        }
    }

执行结果:
在这里插入图片描述
引用类型的拷贝:

class TestArray {
    private int val = 10;
    public int getVal() {
        return val;
    }
    public void setVal(int val) {
        this.val = val;
    }
        }
    public class Prac {
        public static void main(String[] args) {
            TestArray[] testArrays = new TestArray[3];
            testArrays[0] = new TestArray();
            testArrays[1] = new TestArray();
            testArrays[2] = new TestArray();

            TestArray[] testArrays2 = testArrays.clone();

            System.out.println("=====拷贝后======");
            for (int i = 0; i < testArrays.length; i++) {
                System.out.print(testArrays[i].getVal() + " ");
            }
            System.out.println();
            for (int i = 0; i < testArrays2.length; i++) {
                System.out.print(testArrays2[i].getVal()+ " ");
            }
            System.out.println();
            System.out.println("=====修改后======");

            testArrays2[0].setVal(10000);

            for (int i = 0; i < testArrays.length; i++) {
                System.out.print(testArrays[i].getVal()+ " ");
            }
            System.out.println();
            for (int i = 0; i < testArrays2.length; i++) {
                System.out.print(testArrays2[i].getVal()+ " ");
            }
        }

执行结果:
在这里插入图片描述
不难看出,clone()方法也属于浅拷贝。

3、System.arrayCopy()方法拷贝数组

源码:
在这里插入图片描述
public static native void arraycopy(Object src(源数组), int srcPos(原数组的起始位置,不一定是0号位置), Object dest(目的数组), int destPos(目的数组的起始位置), int length(拷贝的长度));
System.arrayCopy()方法底层也是用c/c++写的
简单类型拷贝:

 public static void main(String[] args) {
            int[] array = {1,2,3,4,5};
            int[] array2 = new int[array.length];
            System.arraycopy(array,0,array2,0,array.length);

            System.out.println(Arrays.toString(array));
            System.out.println(Arrays.toString(array2));
            array2[0] = 999;
            System.out.println(Arrays.toString(array));
            System.out.println(Arrays.toString(array2));
        }

执行结果:
在这里插入图片描述
引用类型的拷贝:

public static void main(String[] args) {
            TestArray[] testArrays = new TestArray[3];
            testArrays[0] = new TestArray();
            testArrays[1] = new TestArray();
            testArrays[2] = new TestArray();
           TestArray[] testArrays2 = new TestArray[testArrays.length];
            System.arraycopy(testArrays,0,testArrays2,0,testArrays.length);
            System.out.println("=====拷贝后======");
            for (int i = 0; i < testArrays.length; i++) {
                System.out.print(testArrays[i].getVal() + " ");
            }
            System.out.println();
            for (int i = 0; i < testArrays2.length; i++) {
                System.out.print(testArrays2[i].getVal()+ " ");
            }
            System.out.println();

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

            testArrays2[0].setVal(10000);

            for (int i = 0; i < testArrays.length; i++) {
                System.out.print(testArrays[i].getVal()+ " ");
            }
            System.out.println();
            for (int i = 0; i < testArrays2.length; i++) {
                System.out.print(testArrays2[i].getVal()+ " ");
            }
        }

执行结果:
在这里插入图片描述

4、Arrays.copyOf()方法拷贝数组

        int[] array = {1,2,3,4,5};
        int[] array2 = Arrays.copyOf(array,array.length);

Arrays.copyOf()的源码
在这里插入图片描述
从源码看出,Arrays.copyOf()底层是调用System.arraycopy()方法
简单类型的拷贝

 public static void main(String[] args) {
            int[] array = {1,2,3,4,5};
            int[] array2 = Arrays.copyOf(array,array.length);
            System.out.println(Arrays.toString(array));
            System.out.println(Arrays.toString(array2));
            array2[0] = 999;
            System.out.println(Arrays.toString(array));
            System.out.println(Arrays.toString(array2));
        }

执行结果:
在这里插入图片描述
引用类型的拷贝

 public static void main(String[] args) {
            TestArray[] testArrays = new TestArray[3];
            testArrays[0] = new TestArray();
            testArrays[1] = new TestArray();
            testArrays[2] = new TestArray();
            TestArray[] testArrays2 = Arrays.copyOf(testArrays,testArrays.length);
            System.out.println("=====拷贝后======");
            for (int i = 0; i < testArrays.length; i++) {
                System.out.print(testArrays[i].getVal() + " ");
            }
            System.out.println();
            for (int i = 0; i < testArrays2.length; i++) {
                System.out.print(testArrays2[i].getVal()+ " ");
            }
            System.out.println();
            System.out.println("=====修改后======");

            testArrays2[0].setVal(10000);

            for (int i = 0; i < testArrays.length; i++) {
                System.out.print(testArrays[i].getVal()+ " ");
            }
            System.out.println();
            for (int i = 0; i < testArrays2.length; i++) {
                System.out.print(testArrays2[i].getVal()+ " ");
            }
        }

执行结果:
在这里插入图片描述

总结:

  • 综上所述,数组的四种拷贝方式for /clone/ System.arrayCopy() / Arrays.copyOf()都属于浅拷贝;
  • clone和system.arrayCopy()源码中有native,底层都是用c/c++写出来得
  • Arrays.copyOf 底层调用的是System.arraycopy();
  • clone 会产生新的对象
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值