Java 7中的equals()和deepEquals()

17

方法描述如下:

如果参数深度相等,则返回true,否则返回false...相等性是通过使用第一个参数的equals方法确定的。

对我来说,这意味着如果它们维护引用的每个对象也使用equals()方法相等,并且它们引用的每个对象也相等,那么对象就是深度相等的。因此..相等性是通过使用第一个参数的equals方法确定的。

这与.equals()有什么不同?假设我们恰当地描述了equals,其中对象等于另一个对象是指对象的每个字段也都相等。

请给出一个示例,说明Objects.deepEquals()Objects.equals()之间的区别。

5个回答

18
String[] firstArray  = {"a", "b", "c"};
String[] secondArray = {"a", "b", "c"};

System.out.println("Are they equal 1    ? " + firstArray.equals(secondArray) );
System.out.println("Are they equal 2    ? " + Objects.equals(firstArray, secondArray) );

System.out.println("Are they deepEqual 1? " + Arrays.deepEquals(firstArray, secondArray) );
System.out.println("Are they deepEqual 2? " + Objects.deepEquals(firstArray, secondArray) );

将返回

Are they equal 1    ? false
Are they equal 2    ? false
Are they deepEqual 1? true
Are they deepEqual 2? true

为什么“浅层次”的equals方法返回false呢?这是因为在Java中,对于数组,相等性是由对象标识确定的。在这个例子中,firstArraysecondArray是不同的对象。

如果用String[] secondArray = firstArray代替,则对所有四个测试都会返回true


Java 8+:虽然@Abdull的回答非常好,但在Java 8+中使用数组来区分Object.equals()和Object.deepEquals()是一个坏主意。因为Arrays.deepEquals()使用自己的比较算法,不像Object.deepEquals()。Arrays.deepEquals()甚至可以在多维数组上工作,例如{{"a", "b", "c"}, {"d", "e"}}。此外,还有一个Arrays.equals(),它的行为与firstArray.equals(secondArray)不同。请查看https://docs.oracle.com/javase/8/docs/api/java/util/Objects.html。 - San123

11

如果deepEquals方法的至少一个参数不是数组,则Objects.deepEqualsObjects.equals相同。


2

例子:

import java.util.Arrays;
import java.util.Objects;

public class Main {
    public static void main(String[] args) {
        Integer[] x = { 1, 2 };
        Integer[] y = { 1, 2 };
        System.out.println(Objects.equals(x, y));       // false
        System.out.println(Objects.deepEquals(x, y));   // true
        System.out.println(Arrays.equals(x, y));        // true
        System.out.println(Arrays.deepEquals(x, y));    // true
        System.out.println();

        int[][] a = { { 1, 2 }, { 3, 4 } };
        int[][] b = { { 1, 2 }, { 3, 4 } };
        System.out.println(Objects.equals(a, b));       // false
        System.out.println(Objects.deepEquals(a, b));   // true
        System.out.println(Arrays.equals(a, b));        // false
        System.out.println(Arrays.deepEquals(a, b));    // true
    }
}

文档和反编译代码:

Objects#equals(Object a, Object b): 如果两个参数相等,则返回true,否则返回false。因此,如果两个参数都为null,则返回true;如果只有一个参数为null,则返回false。否则,将使用第一个参数的equals方法来确定相等性。

public static boolean equals(Object a, Object b) {
    return (a == b) || (a != null && a.equals(b));
}

Objects#deepEquals(Object a, Object b): 如果两个参数深度相等,则返回true,否则返回false。如果两个参数都为null,则它们是深度相等的。如果两个参数都是数组,则使用Arrays.deepEquals算法来确定它们是否相等。否则,使用第一个参数的equals方法来确定它们是否相等。


注:本文介绍了Java中的Objects类的deepEquals()方法,该方法用于比较两个对象是否相等。如果您对Java编程有兴趣,可以点击上方链接查看更多相关信息。
public static boolean deepEquals(Object a, Object b) {
    if (a == b)
        return true;
    else if (a == null || b == null)
        return false;
    else
        return Arrays.deepEquals0(a, b);
}

Arrays#equals(Object[] a, Object[] a2): 如果两个指定的对象数组相等,则返回 true。当且仅当两个数组包含相同数量的元素,且两个数组中对应位置的元素都相等时,这两个数组被认为是相等的。

public static boolean equals(Object[] a, Object[] a2) {
    if (a==a2)
        return true;
    if (a==null || a2==null)
        return false;

    int length = a.length;
    if (a2.length != length)
        return false;

    for (int i=0; i<length; i++) {
        if (!Objects.equals(a[i], a2[i]))
            return false;
    }

    return true;
}

Arrays#deepEquals(Object[] a1, Object[] a2): 如果两个指定的数组完全相等,则返回true。 equals(Object[],Object[])方法不同,此方法适用于任意深度的嵌套数组。.

public static boolean deepEquals(Object[] a1, Object[] a2) {
    if (a1 == a2)
        return true;
    if (a1 == null || a2==null)
        return false;
    int length = a1.length;
    if (a2.length != length)
        return false;

    for (int i = 0; i < length; i++) {
        Object e1 = a1[i];
        Object e2 = a2[i];

        if (e1 == e2)
            continue;
        if (e1 == null)
            return false;

        // Figure out whether the two elements are equal
        boolean eq = deepEquals0(e1, e2);

        if (!eq)
            return false;
    }
    return true;
}

static boolean deepEquals0(Object e1, Object e2) {
    assert e1 != null;
    boolean eq;
    if (e1 instanceof Object[] && e2 instanceof Object[])
        eq = deepEquals ((Object[]) e1, (Object[]) e2);
    else if (e1 instanceof byte[] && e2 instanceof byte[])
        eq = equals((byte[]) e1, (byte[]) e2);
    else if (e1 instanceof short[] && e2 instanceof short[])
        eq = equals((short[]) e1, (short[]) e2);
    else if (e1 instanceof int[] && e2 instanceof int[])
        eq = equals((int[]) e1, (int[]) e2);
    else if (e1 instanceof long[] && e2 instanceof long[])
        eq = equals((long[]) e1, (long[]) e2);
    else if (e1 instanceof char[] && e2 instanceof char[])
        eq = equals((char[]) e1, (char[]) e2);
    else if (e1 instanceof float[] && e2 instanceof float[])
        eq = equals((float[]) e1, (float[]) e2);
    else if (e1 instanceof double[] && e2 instanceof double[])
        eq = equals((double[]) e1, (double[]) e2);
    else if (e1 instanceof boolean[] && e2 instanceof boolean[])
        eq = equals((boolean[]) e1, (boolean[]) e2);
    else
        eq = e1.equals(e2);
    return eq;
}

1

deepEquals()用于任意深度的嵌套数组。
equals()用于简单的原始数据类型。
例如:

public class TwoDArray {
    public static void main(String args[]) {
        int a[][] = new int[2][2];
        int b[][] = new int[2][2];
        for(int i=0;i<2;i++)
            for(int j=0;j<2;j++) {
                a[i][j] = i+j;
                b[i][j] = i+j;  
            }
        System.out.println(Arrays.deepEquals(a,b));//return true
        System.out.println(Arrays.equals(a, b));//return false
    }
}

1
这不是一个好的答案,因为它没有尝试解释问题及其解决方法。请添加一些上下文信息、参考资料或解释。谢谢! - Clijsters
我认为Arrays.deepEquals(a,b)不会编译,因为Arrays.deepEquals需要将对象数组作为参数Arrays.deepEquals(Object[],Object[])。 - e2rabi

0

附上我在javarevisited.blogspot.in上找到的一个非常好的例子。

public class ArrayCompareTest {

public static void main(String args[]) {

   //comparing primitive int arrays in Java
    int[] i1 = new int[] {1,2,3,4};
    int[] i2 = new int[] {1,2,3,4};
    int[] i3 = new int[] {0,2,3,4};

    //Arrays.equals() compare Array and return true if both array are equal
    //i..e either both of them are null or they are identical in length, and each pair
    //match each other e.g. i[0]=i2[0], i[1]=i2[1] and so on

    //i1 and i2 should be equal as both contains same elements
    boolean result = Arrays.equals(i1, i2);
    System.out.println("Comparing int array i1: " + Arrays.toString(i1)
                        + " and i1: " + Arrays.toString(i2));
    System.out.println("Does array i1 and i2 are equal : " + result);

    //array ii2 and i3 are not equals as only length is same, first pair is not same
    result = Arrays.equals(i2, i3);
    System.out.println("Comparing int array i2: " + Arrays.toString(i2)
                        + " and i3: " + Arrays.toString(i3));
    System.out.println("Does array i2 and i3 are equal : " + result);

    //comparing floating point or double arrays in Java
    double[] d1 = new double[] {1.5, 2.4, 3.2, 4,1};
    double[] d2 = new double[] {1.5, 2.4, 3.2, 4,1};
    double[] d3 = new double[] {0.0, 2.4, 3.2, 4,1};

    //Comparing two floating-point arrays using Arrays.equals() in Java

    //double array d1 and d2 should be equal - length same, each index matches
    result = Arrays.equals(d1, d2);
    System.out.println("Comparing double array d1: " + Arrays.toString(d1)
                        + " and d2: " + Arrays.toString(d2));
    System.out.println("Does double array d1 and d2 are equal : " + result);

    //double array d2 and d3 is not equal - length same, first pair does not match
    result = Arrays.equals(d2, d3);
    System.out.println("Comparing double array d2: " + Arrays.toString(d2)
                        + " and d3: " + Arrays.toString(d3));
    System.out.println("Does double array d2 and d3 are same : " + result);

    //comparing Object array, here we will use String array
    String[] s1 = new String[]{"One", "Two", "Three"};
    String[] s2 = new String[]{"One", "Two", "Three"};
    String[] s3 = new String[]{"zero", "Two", "Three"};

    //String array s1 and s2 is equal - length same, each pair matches
    result = Arrays.equals(s1, s2);
    System.out.println("Comparing two String array s1: " + Arrays.toString(s1)
                        + " and s2: " + Arrays.toString(s2));

    System.out.println("Are both String array s1 and s2 are equal : " + result);

    //String array s2 and s3 is not equal - length same, first pair different
    result = Arrays.equals(d2, d3);
    System.out.println("Comparing two String array s2: " + Arrays.toString(s2)
                         + " and s3: " + Arrays.toString(s3));

    System.out.println("Are both String array s2 and s3 are equal : " + result);

    //Comparing nested arrays with equals and deepEquals method
    //Arrays.equals() method does not compare recursively,
    //while deepEquals() compare recursively
    //if any element inside Array is type of Array itself,
    //as here second element is String array

    Object[] o1 = new Object[]{"one", new String[]{"two"}};
    Object[] o2 = new Object[]{"one", new String[]{"two"}};

    System.out.println("Object array o1: " + Arrays.toString(o1) + " and o2: "
                        + Arrays.toString(o2));
    System.out.println("Comparing Object Array o1 and o2 with Arrays.equals : "
                        + Arrays.equals(o1, o2));
    System.out.println("Comparing Object Array o1 and o2 with Arrays.deepEquals : "
                        + Arrays.deepEquals(o1, o2));
} 

}

输出: 比较整数数组 i1: [1, 2, 3, 4] 和 i1: [1, 2, 3, 4] i1 和 i2 数组是否相等:true

比较整数数组 i2: [1, 2, 3, 4] 和 i3: [0, 2, 3, 4] i2 和 i3 数组是否相等:false

比较双精度浮点数数组 d1: [1.5, 2.4, 3.2, 4.0, 1.0] 和 d2: [1.5, 2.4, 3.2, 4.0, 1.0] d1 和 d2 数组是否相等:true

比较双精度浮点数数组 d2: [1.5, 2.4, 3.2, 4.0, 1.0] 和 d3: [0.0, 2.4, 3.2, 4.0, 1.0] d2 和 d3 数组是否相等:false

比较两个字符串数组 s1: [One, Two, Three] 和 s2: [One, Two, Three] 判断字符串数组 s1 和 s2 是否相等:true

比较两个字符串数组 s2: [One, Two, Three] 和 s3: [zero, Two, Three] 判断字符串数组 s2 和 s3 是否相等:false

对象数组 o1: [one, [Ljava.lang.String;@19821f] 和 o2: [one, [Ljava.lang.String;@addbf1] 使用 Arrays.equals 比较对象数组 o1 和 o2:false 使用 Arrays.deepEquals 比较对象数组 o1 和 o2:true


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