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

Ach*_*les 39 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");
Run Code Online (Sandbox Code Playgroud)

返回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");
Run Code Online (Sandbox Code Playgroud)

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

pol*_*nts 111

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

true如果两个指定的数组彼此非常相等,则返回.

既然a int[]是an instanceof Object,an int[][]是an instanceof Object[].


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

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

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

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

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

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

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"
Run Code Online (Sandbox Code Playgroud)

以下是事实:

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

从前一点可以清楚地看出,这会引起Arrays.equals(Object[], Object[])过载.来自API:

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

现在应该清楚为什么上面的片段打印"false"; 这是因为Object[]数组的元素不等于上面的定义(因为它int[]有一个equals由对象标识定义的).

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"
Run Code Online (Sandbox Code Playgroud)

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]]"
Run Code Online (Sandbox Code Playgroud)

同样,推理类似:Arrays.toString(Object[])将每个元素视为一个Object,并调用其toString()方法.数组toString()从它们的公共超类继承它Object.

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

  • 还有deepHashCode()http://docs.oracle.com/javase/6/docs/api/java/util/Arrays.html#deepHashCode(java.lang.Object []),这对于创建"值对象"非常有用你想实现'equals()'和'hashCode()'. (3认同)