Java Arrays.equals()为二维数组返回false

时间:2010-04-27 12:17:13

标签: java arrays

我只是很想知道 - 为什么Arrays.equals(double [] [],double [] [])返回false?实际上,当数组具有相同数量的元素并且每个元素是相同的时候?

例如,我进行了以下测试。

double[][] a,  b;
int size =5;

a=new double[size][size];
b=new double[size][size];

for( int i = 0; i < size; i++ )
    for( int j = 0; j < size; j++ ) {
        a[i][j]=1.0;
        b[i][j]=1.0;
    }

if(Arrays.equals(a, b))
    System.out.println("Equal");
else
    System.out.println("Not-equal");

返回false并打印“Not-equal”。

另一方面,如果我有这样的事情:

double[] a,  b;
int size =5;

a=new double[size];
b=new double[size];

for( int i = 0; i < size; i++ ){
    a[i]=1.0;
    b[i]=1.0;
} 

if(Arrays.equals(a, b))
    System.out.println("Equal");
else
    System.out.println("Not-equal");

返回true并打印“Equal”。该方法仅适用于单个尺寸吗?如果是这样,Java中的多维数组有类似的东西吗?

2 个答案:

答案 0 :(得分:109)

使用deepEquals(Object[], Object[])

  

如果两个指定的数组彼此非常相等

,则返回true

由于int[]instanceof Objectint[][]instanceof Object[]


至于为什么 Arrays.equals不能为二维数组“工作”,可以按如下步骤逐步解释:

对于数组,equals是根据对象标识

定义的
System.out.println(
    (new int[] {1,2}).equals(new int[] {1,2})
); // prints "false"

这是因为数组从它们的公共超类Object继承了它们的equals

当然,我们通常希望数组的值相等,这就是java.util.Arrays提供static实用程序方法equals(int[], int[])的原因。

System.out.println(
    java.util.Arrays.equals(
        new int[] {1,2},
        new int[] {1,2}
    )
); // prints "true"

Java中的数组数组

  • int[]instanceof Object
  • int[][]instanceof Object[]
  • int[][] instanceof int[]

Java实际上没有二维数组。它甚至没有真正的多维数组。 Java有数组数组。

java.util.Arrays.equals是“浅”

现在考虑一下这个片段:

System.out.println(
    java.util.Arrays.equals(
        new int[][] {
            { 1 },
            { 2, 3 },
        },
        new int[][] {
            { 1 },
            { 2, 3 },
        }
    )
); // prints "false"

以下是事实:

  • 每个参数都是Object[]
    • 索引0处的元素是int[] { 1 }
    • 索引1处的元素是int[] { 2, 3 }
  • 有两个Object[]个实例
  • 有四个int[]个实例

从前一点可以清楚地看出,这会调用Arrays.equals(Object[], Object[])重载。来自API:

  

如果两个指定的true数组彼此相等,则返回Objects。如果两个数组包含相同数量的元素,则两个数组被视为equal,并且两个数组中的所有相应元素对相等。如果e1,则认为两个对象e2(e1==null ? e2==null : e1.equals(e2))相等。

现在应该清楚为什么上面的代码段会打印"false";这是因为Object[]数组的元素与上述定义不相等(因为int[]的{​​{1}}由对象标识定义。)

equals是“深度”

相反,这是Arrays.deepEquals(Object[], Object[])的作用:

  

如果两个指定的数组彼此相等,则返回java.util.Arrays.deepEquals。与true方法不同,此方法适用于任意深度的嵌套数组。

equals(Object[],Object[])

System.out.println( java.util.Arrays.deepEquals( new int[][] { { 1 }, { 2, 3 }, }, new int[][] { { 1 }, { 2, 3 }, } ) ); // prints "true" Arrays.toString

值得注意的是这两种方法之间的类比,以及我们到目前为止讨论的嵌套数组。

Arrays.deepToString

同样,推理类似:System.out.println( java.util.Arrays.toString( new int[][] { { 1 }, { 2, 3 }, } ) ); // prints "[[I@187aeca, [I@e48e1b]" System.out.println( java.util.Arrays.deepToString( new int[][] { { 1 }, { 2, 3 }, } ) ); // prints "[[1], [2, 3]]" 将每个元素视为Arrays.toString(Object[]),并调用其Object方法。数组从其公共超类toString()继承其toString()

如果您希望Object考虑嵌套数组,则需要使用java.util.Arrays,就像您需要使用deepToString一样。

答案 1 :(得分:0)

java实际上没有多维数组。相反,它只有一维数组,多d数组将是这个1d数组的数组。 String.equals()只能对基本的单块数组执行,因此它不适用于多维数组。