The difference between Objects.equals and Objects.deepEquals

Objects.equals源码 (java.util.Objects#equals)

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

There is no difference between Objects.equals and equals, just to help us increase the handling of null;
it can be understood as:
Objects.equals = equals + handling of null

Objects.equals(null, null);       true
Objects.equals(null, "null");     false
Objects.equals("null", null);     false
Objects.equals("null", "null");   true

Objects.deepEquals源码 (java.util.Objects#deepEquals)

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);
}


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;
}

It can be understood as:
Objects.deepEquals = equals + processing of null + processing of arrays = Objects.equals + processing of arrays


scenes to be used

Ordinary objects that are not arrays

String a = "abc";
String b = "abc";

System.out.println(a.equals(b));               true
System.out.println(Objects.equals(a, b));      true
System.out.println(Objects.deepEquals(a, b));  true

String覆写了的equals()
Person per1 = new Person("name");
Person per2 = new Person("name");

System.out.println(per1.equals(per2));                true
System.out.println(Objects.equals(per1, per2));       true
System.out.println(Objects.deepEquals(per1, per2));   true

因为Person@Data,故覆写了equals

array of primitive types

int[] arr1 = {
    
    1, 2, 3};
int[] arr2 = arr1;
int[] arr3 = {
    
    1, 2, 3};

System.out.println(arr1.equals(arr2));  true
System.out.println(arr1.equals(arr3));  false
数组没有覆写equals,故会使用Object.equals,比较的是地址

System.out.println(Objects.equals(arr1, arr2));  true
System.out.println(Objects.equals(arr1, arr3));  false
数组没有覆写equals,故会使用Object.equals,比较的是地址

System.out.println(Objects.deepEquals(arr1, arr2));  true
System.out.println(Objects.deepEquals(arr1, arr3));  true
deepEquals自己有判断逻辑,调用ArraysSupport.mismatch去比较,本地是调用了元素自身的equals方法

array of object types

String[] arr1 = {
    
    "Tom", "Mary"};
String[] arr2 =arr1;
String[] arr3 = {
    
    "Tom", "Mary"};

System.out.println(arr1.equals(arr2));  true
System.out.println(arr1.equals(arr3));  false

System.out.println(Objects.equals(arr1, arr2));  true
System.out.println(Objects.equals(arr1, arr3));  false

System.out.println(Objects.deepEquals(arr1, arr2));  false
System.out.println(Objects.deepEquals(arr1, arr3));  true

和基本类型的数组一样结论
@Data
public class Person {
    
    
    private String personName;
    public Person(String name) {
    
    
        personName = name;
    }
}

Person per1 = new Person("name1");
Person per2 = new Person("name2");
Person[] arr1 = new Person[] {
    
    per1, per2};
Person[] arr2 = new Person[] {
    
    per1, per2};
System.out.println(arr1.equals(arr2));               false 数组没有覆写equals,故会使用Object.equals,比较的是地址
System.out.println(Objects.deepEquals(arr1, arr2));  true  Person复写了equals,故为值比较

Person[] arr3 = new Person[] {
    
    new Person("name1"), new Person("name2")};
Person[] arr4 = new Person[] {
    
    new Person("name1"), new Person("name2")};
System.out.println(arr3.equals(arr4));               false 数组没有覆写equals,故会使用Object.equals,比较的是地址
System.out.println(Objects.deepEquals(arr3, arr4));  true  Person复写了equals,故为值比较
public class Person {
    
    
    private String personName;
    public Person(String name) {
    
    
        personName = name;
    }
}

Person per1 = new Person("name1");
Person per2 = new Person("name2");
Person[] arr1 = new Person[] {
    
    per1, per2};
Person[] arr2 = new Person[] {
    
    per1, per2};
System.out.println(arr1.equals(arr2));               false 数组没有覆写equals,故会使用Object.equals,比较的是地址
System.out.println(Objects.deepEquals(arr1, arr2));  true  按顺序比较元素的地址

Person[] arr1 = new Person[] {
    
    per1, per2};
Person[] arr2 = new Person[] {
    
    per2, per1};
System.out.println(arr1.equals(arr2));               false 数组没有覆写equals,故会使用Object.equals,比较的是地址
System.out.println(Objects.deepEquals(arr1, arr2));  false 按顺序比较元素的地址

Person[] arr3 = new Person[] {
    
    new Person("name1"), new Person("name2")};
Person[] arr4 = new Person[] {
    
    new Person("name1"), new Person("name2")};
System.out.println(arr3.equals(arr4));               false 数组没有覆写equals,故会使用Object.equals,比较的是地址
System.out.println(Objects.deepEquals(arr3, arr4));  false 按顺序比较元素的地址

in conclusion

When we want to compare whether the contents of two arrays are the same, we use deepEquals; if
the object members in the array do not override the equals method, it is not recommended to use it, and there is even no way to compare it, because only the addresses can be compared

Further Reading

The relationship between hashCode() and equals()
equals, Objects.equals, Objects.deepEquals difference and connection

Guess you like

Origin blog.csdn.net/weixin_37646636/article/details/132185595