Object.equals(a)、Object.equals(a,b)、Objects.deepEquals(a,b)的区别
@Test
public void test1(){
String s1 = "aa";
String s2 = s1;
String s3 = "aa";
System.out.println(s1);
System.out.println(s2);
System.out.println(s3);
System.out.println(s1.equals(s2));
System.out.println(s1.equals(s3));
System.out.println(Objects.equals(s1,s2));
System.out.println(Objects.equals(s1,s3));
System.out.println(Objects.deepEquals(s1,s2));
System.out.println(Objects.deepEquals(s1,s3));
System.out.println("=========================================");
String[] str1={"a","b","c"};
String[] str2=str1;
String[] str3={"a","b","c"};
System.out.println(str1);
System.out.println(str2);
System.out.println(str3);
System.out.println(str1.equals(str2));
System.out.println(str1.equals(str3));
System.out.println(Objects.equals(str1,str2));
System.out.println(Objects.equals(str1,str3));
System.out.println(Objects.deepEquals(str1,str2));
System.out.println(Objects.deepEquals(str1,str3));
System.out.println("==================================");
List<String> list1 = Arrays.asList("a","b","c");
List<String> list2 = list1;
List<String> list3 = Arrays.asList("a","b","c");
System.out.println(list1);
System.out.println(list2);
System.out.println(list3);
System.out.println(list1.equals(list2));
System.out.println(list1.equals(list3));
System.out.println(Objects.equals(list1,list2));
System.out.println(Objects.equals(list1,list3));
System.out.println(Objects.deepEquals(list1,list2));
System.out.println(Objects.deepEquals(list1,list3));
}
运行结果:
aa
aa
aa
true
true
true
true
true
true
=========================================
[Ljava.lang.String;@52aa2946
[Ljava.lang.String;@52aa2946
[Ljava.lang.String;@4de5031f
true
false
true
false
true
true
==================================
[a, b, c]
[a, b, c]
[a, b, c]
true
true
true
true
true
true
由结果可知当对象不为数组时,三者的情况是一样的,当对象为数组时,结果就发生了改变
查看源码分析原因:
Object.equals()源码:
//Obejct 父类的equals方法,比较的是地址
public boolean equals(Object obj) {
return (this == obj);
}
// 因为我们这里用了String类型,String类型重写了父类方法
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String aString = (String)anObject;
if (coder() == aString.coder()) {
return isLatin1() ? StringLatin1.equals(value, aString.value)
: StringUTF16.equals(value, aString.value);
}
}
return false;
}
Objects.equals()源码:
public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}
Objects.deepEquals(a,b)源码:
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;
}
String类里重写了Object的equals方法,首先比较地址如果地址相同直接放true,再判断入参类型,如果类型不是String直接放false,之后再对值进行比较,因此代码第一部分(s1.equals(s2),s1.equals(s3))得到得结果都为true;
Objects.equals()对两个传入的参数a,b比较了地址,如果地址相同直接返回true;
Objects.deepEquals()对两个传入的参数先比较了地址,若地址相同直接返回true,两个参数其中一个为null的情况直接返回false,若传入的是数组,会对数组中的每个值遍历比较;
结论:当比较对象为数组时,deepEquals会比较数组中每个元素的值,若不为数组时三个方法结果一样。。