如何在 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=old
或old=current
使两个数组引用同一事物,因此如果您随后修改current
,old
也会被修改。要将数组的内容复制到另一个数组,请使用 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();
希望它有效。
【讨论】:
不,这行不通。因为分配给局部变量destination
在multiArrayCopy
之后完全没有效果。以上是关于如何在 Java 中复制二维数组?的主要内容,如果未能解决你的问题,请参考以下文章