博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
数组的拷贝及效率
阅读量:4155 次
发布时间:2019-05-25

本文共 5091 字,大约阅读时间需要 16 分钟。

程序如下: 

class C{ 

public static void main(String args[]){ 

      int a[][] = {
{1,2,3},{4,5,6}}; 

      int b[][] = new int[a.length][a[0].length]; 

      System.arraycopy(a,0,b,0,a.length); //通过arraycopy()函数拷贝数组 

      b[0][0] = 4; //改变数组b[0][0]的值 

      System.out.println("a[][]"); 

       for(int i=0;i<2;i++){ 

       for(int j=0;j<3;j++){ 

           System.out.print(a[i][j]+" "); 

       } 

       System.out.println(); 

     } 

     System.out.println("b[][]"); 

     for(int i=0;i<2;i++){ 

     for(int j=0;j<3;j++){ 

         System.out.print(b[i][j]+" "); 

     } 

     System.out.println(); 

    } 



打印的结果如下: 


a[][] 

4 2 3 

4 5 6 

b[][] 

4 2 3 

4 5 6 


而如果把上述程序中的二维数组改为一维数组,结果却不同。程序如下: 


class C{ 

    public static void main(String args[]){ 

    int a[] = {1,2,3}; 

    int b[] = new int[a.length]; 

    System.arraycopy(a,0,b,0,a.length); //通过arraycopy()函数拷贝数组 

    b[0] = 4; //改变数组b[0]的值 

    System.out.println("a[]:"); 

    for(int i=0;i<3;i++){ 

          System.out.print(a[i] + " "); 

    } 

    System.out.println(); 

    System.out.println("b[]:"); 

    for(int i=0;i<3;i++){ 

           System.out.print(b[i] + " "); 

    } 




打印结果如下: 


a[]: 

1 2 3 

b[]: 

4 2 3 


在第一个程序中,用b[0][0] = 4;只改变了数组b[0][0]的值,可是结果却是数组a[0][0]的值也发生了改变。而在第二个程序中,由于是一个一维数组,改变了b[0]的 值,a[0]的值却并没有受到影响,所以问题可能就出在数组的维数上。第一个程序中的a 是一个数组的数组(java 中没有多维数组的概念,只有数组的数组),同理b 也是,那么a 含有两个元素,第一个是指向(1,2,3) 这个数组的引用,第二个是指向(4,5,6)这个数组的引用,而arrayCopy 就是负责把数组的内容copy 过去的,因此 a 的内容 (2 个引用) 被copy 到b 中去了,因此你对b[0][0] 做修改,a 也会同样跟着变化. 

在JAVA里面,可以用复制语句“A=B”给基本类型的数据传递值,但是如果A,B是两个同类型的数组,复制就相当于将一个数组变量的引用传递给另一个数组;如果一个数组发生改变,那么引用同一数组的变量也要发生改变。 

JAVA中复制数组元素值的的方法指深拷贝 

1 使用for循环,将数组的每个元素复制(需要将每个对象调用clone方法,才能实现真正的复制) 

2 使用clone方法,得到数组的值,而不是引用 

3 使用System.arraycopy方法 


注意: 

1.上面方法中arraycopy效率较高。 

2. 以上所说的拷贝数组的方法,只是针对一维数组,对于多维数组,要在每一维用以上方法进行复制才能实现复制数组元素的值而不是引用。 

3. clone 和 arraycopy对二维数组进行复制时,是浅拷贝, 即 


Object[][] aa; 

Object[][] bb = aa.clone(); 

//or bb=System.arraycopy(aa,0,bb, 0, bb.length); 

则: 

boolean b1 = ( aa[i] == bb[i] ); //false 

boolean b2 = (aa[i][j] == bb[i][j]); //true, 可见数组元素只复制了引用。新旧数组指向相同的内存地址,(不论对象数组,还是基本类型数组)。 

        /** 

        * 数组的浅拷贝是指数组拷贝时,只拷贝了数组的地址,新旧数组指向同一数据 

        * 数组的深拷贝,不论数据是基本类型,还是对象类型,都是一样的。 

        * 对数组来说,不一样的地方在于,当为数组元素赋值时,基本类型值传递,对象类型是引用传递。 

        * 

        */ 

        Object[] a = new Object[]{"String", new Integer(1)}; 

        Object[] b = a; 

        

        /** 

        * 数组深拷贝的方法有如下几种: 

        * 1。 调用clone 

        * 2。 调用System.arraycopy 

        * 以上两种对基本类型和对象类型数据效果等同。 

        * 3。 使用FOR循环,将数组的每个元素复制。(注意调用clone方法) 

        * 

        */ 

        

        /* 

        * 当数组数据是基本类型时, 

        */ 

//        int[] array = new int[]{0,1,2,3,4}; 

//        int[] copy = array.clone();               //1.拷贝数据 

//        System.out.println( copy.equals(array)); 

//        System.out.println( copy == array ); 

//        for (int i = 0; i < copy.length; i++) { 

//            System.out.print( copy[i]+", " );     

//            copy[i]++;                            //2.改变新数组数据内容 

//            System.out.print( copy[i]+", " );        

//            System.out.println( array[i]+",");    //3.不影响原始数组 

//        } 

//        System.out.println(); 

        

        

        /* 

        * 当数组数据是对象类型时, 

        */ 

//        Object[] src = new Object[]{ new String("Zhao"), 

//                                         Integer.valueOf(1), 

//                                         Integer.valueOf(2), 

//                                         Integer.valueOf(3), 

//                                         Integer.valueOf(4)};                

//                

//        Object[] dest = src.clone();                //1.拷贝数据 

//        

        Object[] dest = new Object[5]; 

        System.arraycopy(src, 0, dest, 0, dest.length); 

//        

//        System.out.println( dest.equals(src)); 

//        System.out.println( dest == src ); 

//        for (int i = 0; i < dest.length; i++) { 

//            System.out.print( dest[i]+", " );     

//            dest[i] = new String("KE");               //2.改变新数组内容                  

//            System.out.print( dest[i]+", " );        

//            System.out.println( src[i]+",");          //3.不影响原始数组 

//        } 

//        System.out.println(); 

/** 

        * 对多维数组(多维基本类型数组和多维对象数组完全一致。) 

        * 

        */        

        //多维基本类型数组 

        int[][] aa = new int[][]{ 

                {1, 2, 3}, 

                {4, 5, 6}, 

                {7, 8, 9} 

        }; 

        

//        //多维对象类型数组 

//        Object[][] aa = new Object[][]{ 

//                { Integer.valueOf(1),Integer.valueOf(2),Integer.valueOf(3) }, 

//                { Integer.valueOf(4),Integer.valueOf(5),Integer.valueOf(6) }, 

//                { Integer.valueOf(7),Integer.valueOf(8),Integer.valueOf(9) } 

//        }; 

        

        /** 

        * 一维数组下的深拷贝在 多维数组 只是浅拷贝!! 

        */ 

        int[][] bb = aa.clone();                                 //一维数组下的深拷贝,对于二维数组只是浅拷贝!! 

//        int[][] bb = new int[aa.length][aa[0].length]; 

//        System.arraycopy(aa, 0, bb, 0, aa.length); 

        

//        Object[][] bb = aa.clone(); 

        Object[][] bb = new Object[3][3];                              

        System.arraycopy(aa, 0, bb, 0, aa.length);               //一维数组下的深拷贝,对于二维数组只是浅拷贝!! 

        

        

        /** 

        * 二维数组的深拷贝的实现方式!!! 转为一维数组拷贝。 

        */ 

//        for (int i = 0; i < bb.length; i++) {                    //实现深拷贝的方法!!!!!!!!!!!! 

//            System.arraycopy(aa[i], 0, bb[i], 0, aa[i].length); 

//           // bb[i] = aa[i].clone(); 

//        } 

        

        

        System.out.println("## 初始 aa:" );                      //1. 初始原数组 

        for (int i = 0; i < aa.length; i++) { 

            for (int j = 0; j < aa[i].length; j++) { 

                System.out.print(aa[i][j]+" "); 

            } 

            System.out.println( ); 

        } 

        

        System.out.println("## bb = aa.clone() 后bb:" );        //2. 新数组(值等于原数组的值) 

        for (int i = 0; i < bb.length; i++) { 

            for (int j = 0; j < bb[i].length; j++) { 

                System.out.print(bb[i][j]+" "); 

            } 

            System.out.println( ); 

        } 

        

        System.out.println("## bb改变后:" );                    //3.改变新数组后 

        for (int i = 0; i < bb.length; i++) { 

            for (int j = 0; j < bb[i].length; j++) { 

                bb[i][j] += 10; //for 多维基本类型数组 

//                bb[i][j] = new String("Zhao"); //for 多维对象类型数组 

                System.out.print(bb[i][j]+" "); 

            } 

            System.out.println( ); 

        } 

        

        System.out.println("## bb改变后, aa:" );                 //4.输出原数组 

        for (int i = 0; i < aa.length; i++) { 

            for (int j = 0; j < aa[i].length; j++) { 

                System.out.print(aa[i][j]+" "); 

            } 

         

还有和c++不同,java定义int [][]a=new int[3][];是没有问题的,c和c++后面就是必须要有维数,int a[][3];。 


如果list里面全是String[],转为String[][],使用 

(String[][]) bodyDataList.toArray(new String[bodyDataList.size()][]);这样就能转成功,还一直不清楚toArray(x)x里面的东西,因为java里面只有array对象 

转载地址:http://qzgti.baihongyu.com/

你可能感兴趣的文章
用go的flag包来解析命令行参数
查看>>
来玩下go的http get
查看>>
队列和栈的本质区别
查看>>
matlab中inline的用法
查看>>
如何用matlab求函数的最值?
查看>>
Git从入门到放弃
查看>>
java8采用stream对集合的常用操作
查看>>
EasySwift/YXJOnePixelLine 极其方便的画出真正的一个像素的线
查看>>
Ubuntu系统上安装Nginx服务器的简单方法
查看>>
Ubuntu Linux系统下apt-get命令详解
查看>>
ubuntu 16.04 下重置 MySQL 5.7 的密码(忘记密码)
查看>>
Ubuntu Navicat for MySQL安装以及破解方案
查看>>
HTTPS那些事 用java实现HTTPS工作原理
查看>>
oracle函数trunc的使用
查看>>
MySQL 存储过程或者函数中传参数实现where id in(1,2,3,...)IN条件拼接
查看>>
java反编译
查看>>
Class.forName( )你搞懂了吗?——转
查看>>
jarFile
查看>>
EJB与JAVA BEAN_J2EE的异步消息机制
查看>>
数学等于号是=那三个横杠是什么符
查看>>