Objects.equals和Objects.deepEquals区别

亦凉 2024-03-23 20:16 94阅读 0赞

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

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

Objects.equals和equals没啥区别、仅仅帮我们增加对null的处理;
可以理解为:
Objects.equals = equals + 对null的处理

  1. Objects.equals(null, null); true
  2. Objects.equals(null, "null"); false
  3. Objects.equals("null", null); false
  4. Objects.equals("null", "null"); true

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

  1. public static boolean deepEquals(Object a, Object b)
  2. if (a == b)
  3. return true;
  4. else if (a == null || b == null)
  5. return false;
  6. else
  7. return Arrays.deepEquals0(a, b);
  8. }
  9. static boolean deepEquals0(Object e1, Object e2) {
  10. assert e1 != null;
  11. boolean eq;
  12. if (e1 instanceof Object[] && e2 instanceof Object[])
  13. eq = deepEquals ((Object[]) e1, (Object[]) e2);
  14. else if (e1 instanceof byte[] && e2 instanceof byte[])
  15. eq = equals((byte[]) e1, (byte[]) e2);
  16. else if (e1 instanceof short[] && e2 instanceof short[])
  17. eq = equals((short[]) e1, (short[]) e2);
  18. else if (e1 instanceof int[] && e2 instanceof int[])
  19. eq = equals((int[]) e1, (int[]) e2);
  20. else if (e1 instanceof long[] && e2 instanceof long[])
  21. eq = equals((long[]) e1, (long[]) e2);
  22. else if (e1 instanceof char[] && e2 instanceof char[])
  23. eq = equals((char[]) e1, (char[]) e2);
  24. else if (e1 instanceof float[] && e2 instanceof float[])
  25. eq = equals((float[]) e1, (float[]) e2);
  26. else if (e1 instanceof double[] && e2 instanceof double[])
  27. eq = equals((double[]) e1, (double[]) e2);
  28. else if (e1 instanceof boolean[] && e2 instanceof boolean[])
  29. eq = equals((boolean[]) e1, (boolean[]) e2);
  30. else
  31. eq = e1.equals(e2);
  32. return eq;
  33. }

可以理解为:
Objects.deepEquals = equals + 对null的处理 + 对数组的处理 = Objects.equals + 对数组的处理


使用场景

非数组的普通对象

  1. String a = "abc";
  2. String b = "abc";
  3. System.out.println(a.equals(b)); true
  4. System.out.println(Objects.equals(a, b)); true
  5. System.out.println(Objects.deepEquals(a, b)); true
  6. String覆写了的equals()
  7. Person per1 = new Person("name");
  8. Person per2 = new Person("name");
  9. System.out.println(per1.equals(per2)); true
  10. System.out.println(Objects.equals(per1, per2)); true
  11. System.out.println(Objects.deepEquals(per1, per2)); true
  12. 因为Person@Data,故覆写了equals

基本类型的数组

  1. int[] arr1 = {
  2. 1, 2, 3};
  3. int[] arr2 = arr1;
  4. int[] arr3 = {
  5. 1, 2, 3};
  6. System.out.println(arr1.equals(arr2)); true
  7. System.out.println(arr1.equals(arr3)); false
  8. 数组没有覆写equals,故会使用Object.equals,比较的是地址
  9. System.out.println(Objects.equals(arr1, arr2)); true
  10. System.out.println(Objects.equals(arr1, arr3)); false
  11. 数组没有覆写equals,故会使用Object.equals,比较的是地址
  12. System.out.println(Objects.deepEquals(arr1, arr2)); true
  13. System.out.println(Objects.deepEquals(arr1, arr3)); true
  14. deepEquals自己有判断逻辑,调用ArraysSupport.mismatch去比较,本地是调用了元素自身的equals方法

对象类型的数组

  1. String[] arr1 = {
  2. "Tom", "Mary"};
  3. String[] arr2 =arr1;
  4. String[] arr3 = {
  5. "Tom", "Mary"};
  6. System.out.println(arr1.equals(arr2)); true
  7. System.out.println(arr1.equals(arr3)); false
  8. System.out.println(Objects.equals(arr1, arr2)); true
  9. System.out.println(Objects.equals(arr1, arr3)); false
  10. System.out.println(Objects.deepEquals(arr1, arr2)); false
  11. System.out.println(Objects.deepEquals(arr1, arr3)); true
  12. 和基本类型的数组一样结论
  13. @Data
  14. public class Person {
  15. private String personName;
  16. public Person(String name) {
  17. personName = name;
  18. }
  19. }
  20. Person per1 = new Person("name1");
  21. Person per2 = new Person("name2");
  22. Person[] arr1 = new Person[] {
  23. per1, per2};
  24. Person[] arr2 = new Person[] {
  25. per1, per2};
  26. System.out.println(arr1.equals(arr2)); false 数组没有覆写equals,故会使用Object.equals,比较的是地址
  27. System.out.println(Objects.deepEquals(arr1, arr2)); true Person复写了equals,故为值比较
  28. Person[] arr3 = new Person[] {
  29. new Person("name1"), new Person("name2")};
  30. Person[] arr4 = new Person[] {
  31. new Person("name1"), new Person("name2")};
  32. System.out.println(arr3.equals(arr4)); false 数组没有覆写equals,故会使用Object.equals,比较的是地址
  33. System.out.println(Objects.deepEquals(arr3, arr4)); true Person复写了equals,故为值比较
  34. public class Person {
  35. private String personName;
  36. public Person(String name) {
  37. personName = name;
  38. }
  39. }
  40. Person per1 = new Person("name1");
  41. Person per2 = new Person("name2");
  42. Person[] arr1 = new Person[] {
  43. per1, per2};
  44. Person[] arr2 = new Person[] {
  45. per1, per2};
  46. System.out.println(arr1.equals(arr2)); false 数组没有覆写equals,故会使用Object.equals,比较的是地址
  47. System.out.println(Objects.deepEquals(arr1, arr2)); true 按顺序比较元素的地址
  48. Person[] arr1 = new Person[] {
  49. per1, per2};
  50. Person[] arr2 = new Person[] {
  51. per2, per1};
  52. System.out.println(arr1.equals(arr2)); false 数组没有覆写equals,故会使用Object.equals,比较的是地址
  53. System.out.println(Objects.deepEquals(arr1, arr2)); false 按顺序比较元素的地址
  54. Person[] arr3 = new Person[] {
  55. new Person("name1"), new Person("name2")};
  56. Person[] arr4 = new Person[] {
  57. new Person("name1"), new Person("name2")};
  58. System.out.println(arr3.equals(arr4)); false 数组没有覆写equals,故会使用Object.equals,比较的是地址
  59. System.out.println(Objects.deepEquals(arr3, arr4)); false 按顺序比较元素的地址

结论

当我们想要比较两个数组内容是否相同时,就用deepEquals;
数组中的对象成员没有重写equals方法,则不推荐使用、甚至都没有办法比较、因为只能比较地址

Further Reading

hashCode()和equals()的关系
equals、Objects.equals、Objects.deepEquals区别和联系

发表评论

表情:
评论列表 (有 0 条评论,94人围观)

还没有评论,来说两句吧...

相关阅读

    相关 "&""&&"、"|""||"的区别

    一、逻辑运算: 与操作:“&”表示所有的判断条件都要进行判断,“&&”如果前面的条件返回的是false,那么后面的条件将不再执行,最终的结果就是false。 或操作:“