【问题标题】:Java int[][] array objectJava int[][] 数组对象
【发布时间】:2012-03-13 13:34:18
【问题描述】:

我已经定义了一个int[][] 对象。因为它是一个对象,如果我将它作为参数发送给一个方法,它只会发送它的引用,因此对方法中数组的任何更改都会在主程序中影响它。所以我想在方法中克隆这个对象,但我不确定如何完成。

我在想这样的事情:

private void myMethod( int[][] array )
{
    //Define our temporary array (clone)
    int[][] newArray = new int[3][3];

    //Go through the elements of the array
    for .... row = 0; row < ..; row++
        for ..... col = 0; col < ..; col++
           //Copy individual elements from one array to another
           newArray[row][col] = array[row][col];
}

但是上面的代码会将数组中的每个元素作为值复制到 newArray 中(所以...该项目的克隆),还是只是引用?

如果是这样,如何做到这一点。如果我要使用 ArrayLists 而不是 int[][] 对象,则有 clone() 方法或类似的方法,但我没有 int[][] 对象的方法:(

另外,如果我没记错的话,如果我在方法 newArray = array 中执行此操作,那将再次复制引用,因此两者都将指向同一个 int[][] 对象:(

附:我知道我可以测试一下,但我想和你们讨论一下,看看到底是什么。

【问题讨论】:

  • 您为什么不对其进行测试,找出发生了什么,然后针对您不理解的任何问题提出澄清问题?
  • 我不认为 int[][] 是一个对象,所以你不必担心。
  • @drgomesp:是的,所有数组都是引用类型。
  • @JonSkeet 很高兴知道,谢谢。

标签: java arrays reference multidimensional-array


【解决方案1】:

但是上面的代码会将数组中的每个元素作为值复制到 newArray 中(所以...该项目的克隆),还是只是引用?

您正在复制数组的每个元素,每个元素都是int,所以你很好。新数组将完全独立于原始数组。

请注意,如果您这样做了:

int[][] newArray = new int[3][];
for (int i = 0; i < 3; i++) {
    newArray[i] = array[i];
}

...然后那个只会将三个现有int[]数组的引用复制到newArray中。但是您分配了一组全新的数组(一个 int[][] 和 3 个 int[]),所以它们都是独立的。

【讨论】:

    【解决方案2】:

    您可以在矩阵和与矩阵中的一行对应的每个数组上使用clone(),因为您正在克隆原始值矩阵,所以它可以正常工作,如下所示:

    int[][] matrix = new int[3][3];
    // ... matrix gets filled ...
    int[][] copy = matrix.clone();
    for (int i = 0; i < matrix.length; i++)
        copy[i] = matrix[i].clone();
    

    上面将创建一个独立于matrixcopy矩阵,这意味着您可以更改副本的值而不影响原始值。

    【讨论】:

    • 第一个 clone() 调用没有意义 - 鉴于您要覆盖每个元素,为什么不直接使用 int[][]copy = new int[3][];
    • @JonSkeet 我最初的答案是这样的 (int[][] copy = new int[matrix.length][]),但为了使用 clone() 操作而改变了它。我认为这两种选择在性能上都没有明显差异,更多的是一致性问题 - 如果它是一个克隆,那么它就是一个克隆。
    • 我认为它具有误导性。您想要数组引用的副本,那么为什么要像这样做一样编写代码呢?我认为没有第一次克隆电话会更清楚。如果您试图向某人解释您希望代码执行的操作,您会说“现在我们要创建一个 int[] 引用数组,它与原始数组中现有的 int[] 引用相同”?
    • 我想要一个矩阵的克隆,对我来说这样更清楚。
    • 我想说,使用您当前的代码,一些维护工程师会很想问自己,“我们为什么要费心克隆“子”阵列?我们已经在克隆上一行中的数组!让我们摆脱那个循环......“砰。您正在做不需要的工作,这让您看起来想要完成这项工作......这使得代码的目的不太清楚。
    【解决方案3】:

    原始类型,例如int,不是引用类型。因此,遍历所有项目并逐个复制它们将按值复制。

    总之,你的代码是正确的。

    【讨论】:

    • 那为什么这些家伙会说其他话呢? stackoverflow.com/questions/9644896/…
    • @AndreiBogdan:数组本身就是一个参考。这个答案是正确的。但是数组的每个int 项都是一个值。
    【解决方案4】:

    int 是一种原始类型,您总是将它们作为值而不是作为引用传递,因此您的代码确实会创建数组的新副本。

    您可能要考虑使用 Arrays.copyOf(),它可能会更快。

    【讨论】:

    • 那为什么这些家伙会说其他话呢? stackoverflow.com/questions/9644896/…
    • int 是原始类型,int[][] 不是原始类型。
    • 我不是说 int 不是原始类型,也不是说原始数组是原始类型。我说他的代码创建了一个新副本,它确实如此。
    猜你喜欢
    • 1970-01-01
    • 2021-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-13
    相关资源
    最近更新 更多