Java中数组的比较的真相

最近在去除冗余代码的时候,稍微比较了一下两个数组,结果和我预想中的不一样,简单总结一下。

比如比较两个byte[]数组,在保证其中一个不为null的情况下,这样就能判断出其内容是否相同。其实不然,比如看下列代码。

[java][/java] 
  1. import java.util.Arrays;
  2. public class ArrayCompareRoot {
  3.     public static void main(String[] args) {
  4.         final String s = “Google”;
  5.         byte[] content1 = s.getBytes();
  6.         byte[] content2 = s.getBytes();
  7.         compareAddress(content1, content2);
  8.         compareContent(content1, content2);
  9.         compare(content1, content2);
  10.         compareObjectArrays();
  11.     }
  12.     private static final void compareAddress(byte[] value1, byte[] value2) {
  13.         System.out.println(“value1 compare value2 by address = ” + (value1 == value2));
  14.     }
  15.     private static final void compareContent(byte[] value1, byte[] value2) {
  16.         System.out.println(“value1 commpare value2 by content = ” + (value1.equals(value2)));
  17.     }
  18.     private static final void compare(byte[] value1, byte[] value2) {
  19.         System.out.println(“value1 compare value2 = ” + Arrays.equals(value1, value2));
  20.     }
  21.     private static final void compareObjectArrays() {
  22.         Book[] books1 = new Book[1];
  23.         Book[] books2 = new Book[1];
  24.         Book book = new Book();
  25.         books1[0] = book;
  26.         books2[0] = book;
  27.         System.out.println(“compare object array = ” + (books1.equals(books2)));
  28.         System.out.println(“compare object arrays= ” + Arrays.equals(books1, books2));
  29.     }
  30.     static class Book {
  31.         @Override
  32.         public boolean equals(Object obj) {
  33.             return true;
  34.         }
  35.         @Override
  36.         public int hashCode() {
  37.             return 1;
  38.         }
  39.     }
  40. }

运行结果如下:
value1 compare value2 by address = false
value1 commpare value2 by content = false
value1 compare value2 = true
compare object array = false
compare object arrays= true
仔细研究一下三个比较方法就明白了。
compareAddress()只是单纯比较两个数组的内存地址。
compareContent()虽然调用了equals的方法,但是实际上数组调用的equals方法是Object的equals方法。而Object的equals方法内容如下:

[java][/java]
  1. public boolean equals(Object obj) {
  2.     return (this == obj);
  3. }

看到源码后发现,这个方法也是比较内存地址。
compare方法调用的是一个工具类的方法,及Arrays.equals(byte[],byte[])方法,其实现逻辑为:

[java][/java] 

  1. public static boolean equals(byte[] a, byte[] a2) {
  2.         if (a==a2)
  3.             return true;
  4.         if (a==null || a2==null)
  5.             return false;
  6.         int length = a.length;
  7.         if (a2.length != length)
  8.             return false;
  9.         for (int i=0; i<length; i++)
  10.             if (a[i] != a2[i])
  11.                 return false;
  12.         return true;
  13. }

compareObjectArrays 比较了两个对象数组,结果也是一样的。
个人理解数组就是特殊的Object,它具有Object的接口,不增加也不减少。
注意,在重写equals方法的同时,应该重写hashCode()方法。

标签