[转载自百度文库]数组拷贝

在看这篇文章前,我先解释一下:

1. arraycopy是浅拷贝

浅拷贝:只复制一个对象,对象内部存在的指向其他对象数组或者引用则不复制

深拷贝:对象,对象内部的引用均复制


举个例子

a. 一维数组只拷贝数组对象,若元素为值,则值也会拷贝;若 元素为引用,则只拷贝引用的值(地址)

b. 学过C语言指针的都知道,一维数组的数组名是一个指针,二维数组数组名是一个二级指针,它指向了 一个指向元素的一级指针。arraycopy拷贝的是一维数组的指针值,同样的若是二维指针同样只拷贝二级指针的指针值(一级指针的地址值),所以以及指针所指向的那片元素内存并没有拷贝,所以需要再次加一个循环手动给每一个一级指针再使用一次arraycopy。


原文链接有代码:https://wenku.baidu.com/view/67531d027375a417866f8f90.html


拷贝数组

数组一旦创建后,其大小不可调整。然而,你可使用相同的引用变量来引用一个全新的数组:

int[] myArray = new int [6];

myArray = new int[10];

在这种情况下,第一个数组被丢弃,除非对它的其它引用保留在其它地方。

Java编程语言在System类中提供了一种特殊方法拷贝数组,该方法被称作arraycopy()。例如,araycopy可作如下使用:

int[] myArray = { 1, 2, 3, 4, 5, 6 };    // 原始数组

int[] hold = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };    // 新的更大的数组

 

System.arraycopy(myArray, 0, hold, 0, myArray.length); // 从没有Array拷贝所有元素到hold,从下标0开始

这时,数组hold有如下内容:1,2,3,4,5,6,4,3,2,1。

注意:如果数组保存的是基本类型的话直接把值拷贝过来。如果数组存放的是引用类型(类类型,数组类型(多维数组的拷贝)等),那么拷贝的是引用类型的地址,请看下面的例子:

例5

class AA {

   int i;

 

   public AA(int ii) {

      i = ii;

   }

}

 

public class TestArrayCopy {

   public static void main(String[] args) {

      // 声明数组并初始化,源数组

      AA str1[] = new AA[] { new AA(1), new AA(2), new AA(3), new AA(4) };

      // 拷贝的目的数组

      AA str2[] = new AA[str1.length];

      // 完全拷贝,array方法参数的介绍看api

      System.arraycopy(str1, 0, str2, 0, str1.length);

      // 改变目的数组

      str2[1].i = 5;

      // 打印原始数组,如果没有改变说明是两个数组

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

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

      }

     

   }

}

                       

显然,数组发生了改变,也就是经过拷贝操作后,原始的数组和新拷贝的数组没有分离,因为所拷贝的将是元素的引用。

对于多维数组,由于数组本身是引用类型,所以其拷贝特性与引用类型数组相同。

例6

public class TestMutipleDemensionArrayCopy {

   public static void main(String[] args) {

      // 定义数组的数组

      int[][] source = new int[5][];

 

      // 定义目的数组

      int[][] target1 = new int[5][];

      int[][] target2 = new int[5][];

 

      // 给源数组赋值

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

         source[i] = new int[i + 1];

         // int temp=i;

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

            source[i][j] = j + 1;

      }

      // 打印源数组的数据

      System.out.println("-------------源数据-------------");

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

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

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

         System.out.println();

      }

      // 数组的拷贝(浅拷贝)

      System.arraycopy(source, 0, target1, 0, source.length);

      // 改变目的1数组的值

      target1[1][0] = 100;

      // 打印源数组的信息,可以看到值改变,说明没有深拷贝

      System.out.println("-----------浅拷贝后输出-----------");

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

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

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

         System.out.println();

      }

 

      // 数组的"深"拷贝(一级指针深拷贝),先拷贝”第一维“的

      System.arraycopy(source, 0, target2, 0, source.length);

      // 再"深"拷贝(一级指针深拷贝)

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

         target2[i] = new int[i + 1];

         System.arraycopy(source[i], 0, target2[i], 0, i + 1);

      }

      // 改变目的2数组的数据

      target2[1][0] = 999;

      // 打印源数组的信息,可以看到值没有改变,说明是"深"拷贝(一级指针深拷贝)

      System.out.println("-----------"深"拷贝后输出未把100改成999-----------");

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

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

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

         System.out.println();

      }

   }

}


关于对象的深复制与潜复制看我下一篇文章

猜你喜欢

转载自blog.csdn.net/csdn9988680/article/details/78160094