Objects.equals和Objects.deepEquals区别
Objects.equals源码 (java.util.Objects#equals)
public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}
Objects.equals和equals没啥区别、仅仅帮我们增加对null的处理;
可以理解为:
Objects.equals = equals + 对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;
}
可以理解为:
Objects.deepEquals = equals + 对null的处理 + 对数组的处理 = Objects.equals + 对数组的处理
使用场景
非数组的普通对象
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
基本类型的数组
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方法
对象类型的数组
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 按顺序比较元素的地址
结论
当我们想要比较两个数组内容是否相同时,就用deepEquals;
数组中的对象成员没有重写equals方法,则不推荐使用、甚至都没有办法比较、因为只能比较地址
Further Reading
hashCode()和equals()的关系
equals、Objects.equals、Objects.deepEquals区别和联系
还没有评论,来说两句吧...