如何在 Java 中复制二维数组?

Posted

技术标签:

【中文标题】如何在 Java 中复制二维数组?【英文标题】:How do I copy a 2 Dimensional array in 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.***.com/2010/08/the-death-of-meta-tags 可以将问题声明为作业问题。但是标签用于分类,“作业”不是一个好的分类器,IMO 【参考方案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 之后完全没有效果。

以上是关于如何在 Java 中复制二维数组?的主要内容,如果未能解决你的问题,请参考以下文章

如何在java中声明一个二维数组的调用? [复制]

请问java中深度copy一个二维数组是啥意思?怎么用代码实现?

如何将一个二维数组中的内容复制到另一个二维数组

如何在 Java 中对二维数组进行深拷贝?

java中二维数组的排序

如何在 C 中动态分配二维数组? [复制]