在Java中复制一个二维数组

66

我有一个名为matrix的int类型二维数组,我想将其复制到方法中的本地变量中以便于编辑。

最好的复制方式是什么,我遇到了一些问题。

例如:

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

    //do some stuff here
    return true;
}
5个回答

103

有两种好的方法可以复制数组,一种是使用clone,另一种是使用System.arraycopy()

以下是在2D情况下如何使用clone:

int [][] myInt = new int[matrix.length][];
for(int i = 0; i < matrix.length; i++)
    myInt[i] = matrix[i].clone();

使用System.arraycopy()时,您需要:

int [][] myInt = new int[matrix.length][];
for(int i = 0; i < matrix.length; i++)
{
  int[] aMatrix = matrix[i];
  int   aLength = aMatrix.length;
  myInt[i] = new int[aLength];
  System.arraycopy(aMatrix, 0, myInt[i], 0, aLength);
}

我没有基准测试,但我可以拿出我的个人经验来打赌,它们比自己做更快且失误更少。特别是,System.arraycopy() 它是使用本地代码实现的。


7
Arrays.copyOf()也可以使用。 - Pete Kirkham
3
皮特是正确的。但Arrays.copyOf()使用System.arraycopy(),因为假设结果的长度可能与原始长度不同而增加了开销。在这种情况下,我们确定结果的大小,因此使用clone()和System.arraycopy()更有效率,因为它们是本地化的。尽管如此,也可以使用Arrays.copyOf()。 - NawaMan
2
@PeteKirkham Arrays.copyOf() 不会深复制一个二维矩阵。它只是引用相同的第二维数组。 - Sachin Verma
1
@SachinVerma 是的。与第二个示例中的新建和arraycopy不同,您可以进行一个库调用来完成两者。 - Pete Kirkham

20

在Java 8中可以使用流来复制2D数组。

@Test
public void testCopy2DArray() {
   int[][] data = {{1, 2}, {3, 4}};
   int[][] dataCopy = Arrays.stream(data)
             .map((int[] row) -> row.clone())
             .toArray((int length) -> new int[length][]);

   assertNotSame(data, dataCopy);
   assertNotSame(data[0], dataCopy[0]);
   assertNotSame(data[1], dataCopy[1]);

   dataCopy[0][1] = 5;
   assertEquals(2, data[0][1]);
   assertEquals(5, dataCopy[0][1]);
}

17
将所有的lambda表达式折叠成方法引用:Arrays.stream(data).map(int[]::clone).toArray(int[][]::new); 但请注意,对于巨大的数组,本机的 System.arraycopy 应该更快(可能?),除非你将流并行化。 - NIA
2
@NIA clone() 在 Oracle JVM 上的速度与 System.arraycopy() 几乎相同:两者都是本地方法。你的代码是我在所有答案和评论中看到的最好的。 - WestCoastProjects

7

您没有初始化本地的二维数组。

int[][] myInt = new int[matrix.length][];
for(int i = 0; i < matrix.length; i++)
{
  myInt[i] = new int[matrix[i].length];
  for (int j = 0; j < matrix[i].length; j++)
  {
    myInt[i][j] = matrix[i][j];
  }
}

1
如果数据量很大,你应该考虑使用适当的线性代数库,比如colt或者nd4j。如果数组不是单维的,System.arraycopy可能只会稍微快一点。否则,它无法像numpy或R一样将整个数据作为一个单元进行复制并重塑。

-15

你也可以像这样编写代码 myInt = matrix.clone();


11
将会创建一个矩阵,其中行数组与原始矩阵共享。 - Pete Kirkham

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接