对于二维数组,Java Arrays.equals()返回false

我只是好奇知道 – 为什么Arrays.equals(double [] [],double [] [])返回false? 当实际上数组有相同数量的元素,每个元素是相同的?

例如,我进行了以下testing。

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并打印“不等于”。

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

 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中的multidimensional array有什么相似之处?

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

如果两个指定的数组深度相等 ,则返回true

由于int[]instanceof Object一个instanceof Object ,因此int[][]instanceof Object[]一个instanceof Object[]


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

对于数组, equals用对象标识来定义

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

这是因为数组从它们的公共超类Objectinheritance它们的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[]一个instanceof Object[]
  • 一个int[][] 不是一个instanceof int[]

Java并没有真正的二维数组。 它甚至没有真正的multidimensional array。 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:

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

现在应该清楚为什么上面的片段打印"false" ; 这是因为Object[]数组的元素与上面的定义不相同(因为int[]等式由object identity定义)。

java.util.Arrays.deepEquals是“深”

相反,这是Arrays.deepEquals(Object[], Object[])所做的:

如果两个指定的数组深度相等,则返回true 。 与equals(Object[],Object[])方法不同,此方法适用于任意深度的嵌套数组。

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

Arrays.toStringArrays.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()方法。 数组从它们的公共超类Objectinheritance它的toString()

如果你想java.util.Arrays考虑嵌套数组,你需要使用deepToString ,就像你需要使用deepEquals

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