【问题标题】:How do I copy a 2 Dimensional array in Java?如何在 Java 中复制二维数组?
【发布时间】:2011-08-02 18:53:09
【问题描述】:

我需要为我正在进行的项目制作一个相当大的二维数组的副本。我有两个二维数组:

int[][]current;
int[][]old;

我也有两种复制方法。我需要复制数组,因为 current 会定期更新。

public void old(){
  old=current
}

public void keepold(){
  current=old
}

但是,这不起作用。如果我要调用 old,对 current 进行更新,然后调用 keepold,current 将不等于原来的值。为什么会这样?

谢谢

【问题讨论】:

  • 当您发现自己需要复制多维数组时,您可能会发现是时候考虑创建一个新类来更好地管理这些数据了。
  • 你知道如何在Java中复制一维数组吗?
  • blog.stackoverflow.com/2010/08/the-death-of-meta-tags 可以将问题声明为作业问题。但是标签用于分类,“作业”不是一个好的分类器,IMO

标签: java arrays multidimensional-array copy


【解决方案1】:

从 Java 8 开始,使用流 API:

int[][] copy = Arrays.stream(matrix).map(int[]::clone).toArray(int[][]::new);

【讨论】:

  • 很好。真的很好。
  • 它比这里的其他答案快吗?
  • 可能,流式 API 已经高度优化,toArray 方法中的初始化也是如此。调整数组大小很少是一个好的选择。
  • IntelliJ 对方法引用有话要说。一个可爱的解决方案! Arrays.stream(grid).map(int[]::clone).toArray(int[][]::new);
  • 为什么这里不需要指定数组大小例如int[3][3]::new??
【解决方案2】:

current=oldold=current 使两个数组引用同一事物,因此如果您随后修改currentold 也会被修改。要将数组的内容复制到另一个数组,请使用 for 循环

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

PS:对于一维数组,可以避免使用Arrays.copyOf创建自己的for循环

【讨论】:

  • 谢谢! Arrays.deepEquals(current, old) 是否同样有效?
  • 没有。什么 Arrays.deepEquals 比较两个数组,如果它们的内容相同则返回 true。 Arrays.copyOf 同样适用于 一维 数组
  • 你不应该将旧的分配给当前的而不是相反
【解决方案3】:
/**
 * Clones the provided array
 * 
 * @param src
 * @return a new clone of the provided array
 */
public static int[][] cloneArray(int[][] src) {
    int length = src.length;
    int[][] target = new int[length][src[0].length];
    for (int i = 0; i < length; i++) {
        System.arraycopy(src[i], 0, target[i], 0, src[i].length);
    }
    return target;
}

是否可以修改此代码以支持 n 维对象数组

您需要支持任意长度的数组并检查 src 和目标是否具有相同的维度,您还需要递归地复制每个数组的每个元素,以防万一Object 也是一个数组。

自从我发布此内容以来已经有一段时间了,但我发现了一种创建 n 维数组类的 nice example 方法。该类在构造函数中采用零个或多个整数,指定每个维度的相应大小。该类使用底层 flat 数组 Object[] 并使用维度和乘数数组计算每个元素的索引。 (这就是 C 编程语言中数组的处理方式。)

复制NDimensionalArray 的实例与复制任何其他二维数组一样简单,但您需要断言每个NDimensionalArray 对象具有相同的维度。这可能是最简单的方法,因为没有递归,这使得表示和访问更加简单。

【讨论】:

    【解决方案4】:

    我解决了它编写一个简单的函数来使用 System.arraycopy 复制多维 int 数组

    public static void arrayCopy(int[][] aSource, int[][] aDestination) {
        for (int i = 0; i < aSource.length; i++) {
            System.arraycopy(aSource[i], 0, aDestination[i], 0, aSource[i].length);
        }
    }
    

    或者实际上我为我的用例改进了它:

    /**
     * Clones the provided array
     * 
     * @param src
     * @return a new clone of the provided array
     */
    public static int[][] cloneArray(int[][] src) {
        int length = src.length;
        int[][] target = new int[length][src[0].length];
        for (int i = 0; i < length; i++) {
            System.arraycopy(src[i], 0, target[i], 0, src[i].length);
        }
        return target;
    }
    

    【讨论】:

      【解决方案5】:

      你也可以这样做:

      public static int[][] copy(int[][] src) {
          int[][] dst = new int[src.length][];
          for (int i = 0; i < src.length; i++) {
              dst[i] = Arrays.copyOf(src[i], src[i].length);
          }
          return dst;
      }
      

      【讨论】:

        【解决方案6】:

        使用 java 8 可以做到这一点

        int[][] destination=Arrays.stream(source)
                            .map(a ->  Arrays.copyOf(a, a.length))
                            .toArray(int[][]::new);
        

        【讨论】:

        • 为什么这里不需要指定数组大小例如int[3][3]::new?
        【解决方案7】:

        java中的数组都是对象,所有的对象都是passed by reference。为了真正“复制”一个数组,而不是为数组创建另一个名称,您必须创建一个新数组并复制所有值。请注意, System.arrayCopy 将完全复制一维数组,但不是二维数组。原因是 2D 数组实际上是 1D 数组的 1D 数组,arrayCopy 通过指针复制指向相同的内部 1D 数组。

        【讨论】:

        • 数组不是对象。数组变量是引用,类似于对象变量是引用,但它们不是对象。
        • 数组是对象。 Java 语言规范第 10 章.. 在 Java 编程语言中,数组是对象(第 4.3.1 节),是动态创建的,并且可以分配给 Object 类型的变量(第 4.3.2 节)。 Object 类的所有方法都可以在数组上调用。 docs.oracle.com/javase/specs/jls/se7/html/….
        【解决方案8】:
        current = old ;
        

        赋值操作不会将一个数组的元素复制到另一个数组。您只是让current 矩阵引用old 矩阵。你需要做一个成员明智的副本。

        【讨论】:

          【解决方案9】:

          我正在使用这个功能:

          public static int[][] copy(final int[][] array) {
              if (array != null) {
                  final int[][] copy = new int[array.length][];
          
                  for (int i = 0; i < array.length; i++) {
                      final int[] row = array[i];
          
                      copy[i] = new int[row.length];
                      System.arraycopy(row, 0, copy[i], 0, row.length);
                  }
          
                  return copy;
              }
          
              return null;
          }
          

          这种方法的最大优点是它还可以复制不具有相同行数的数组,例如:

          final int[][] array = new int[][] { { 5, 3, 6 }, { 1 } };
          

          【讨论】:

            【解决方案10】:

            以下是使用循环的方法。

            public static int[][] makeCopy(int[][] array){
                b=new int[array.length][];
            
                for(int row=0; row<array.length; ++row){
                    b[row]=new int[array[row].length];
                    for(int col=0; col<b[row].length; ++col){
                        b[row][col]=array[row][col];
                    }
                }
                return b;
            }
            

            【讨论】:

              【解决方案11】:

              你也可以使用 for each 循环

              int r=0;
              for(int[] array:old){
                  int c=0;
                  for(int element:array)
                      current[r][c++]=array;
                  r++;
              }
              

              或者

              int c=0;
              for(int array[]:old){
                  System.arraycopy(array,0,current[c++],0,array.length);
              }
              

              但是类似:

              int c=0;
              for(int[] array:old){
                  current[c++]=array;
              }
              

              这是错误的,因为它只会复制 old 子数组的引用,并且对 old 所做的更改将反映在当前。

              【讨论】:

                【解决方案12】:
                public  static byte[][] arrayCopy(byte[][] arr){
                    if(arr!=null){
                        int[][] arrCopy = new int[arr.length][] ;
                        System.arraycopy(arr, 0, arrCopy, 0, arr.length);
                        return arrCopy;
                    }else { return new int[][]{};}
                }
                

                【讨论】:

                  【解决方案13】:

                  你可以试试下面的代码,

                  public void multiArrayCopy(int[][] source,int[][] destination){
                  destination=source.clone();}
                  

                  希望它有效。

                  【讨论】:

                  • 不,这行不通。因为分配给局部变量destinationmultiArrayCopy 之后完全没有效果。
                  猜你喜欢
                  • 2018-04-03
                  • 2015-07-12
                  • 1970-01-01
                  • 1970-01-01
                  • 2022-12-18
                  • 1970-01-01
                  • 1970-01-01
                  • 2021-03-02
                  相关资源
                  最近更新 更多