Java中数组的比较的真相 (一)

2014-11-24 10:21:33 · 作者: · 浏览: 0


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

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


import java.util.Arrays; 
  
  
public class ArrayCompareRoot { 
    public static void main(String[] args) { 
        final String s = "Google"; 
        byte[] content1 = s.getBytes(); 
        byte[] content2 = s.getBytes(); 
        compareAddress(content1, content2); 
        compareContent(content1, content2); 
        compare(content1, content2); 
        compareObjectArrays(); 
    } 
  
    private static final void compareAddress(byte[] value1, byte[] value2) { 
        System.out.println("value1 compare value2 by address = " + (value1 == value2)); 
    } 
  
    private static final void compareContent(byte[] value1, byte[] value2) { 
        System.out.println("value1 commpare value2 by content = " + (value1.equals(value2))); 
    } 
  
    private static final void compare(byte[] value1, byte[] value2) { 
        System.out.println("value1 compare value2 = " + Arrays.equals(value1, value2)); 
    } 
  
    private static final void compareObjectArrays() { 
        Book[] books1 = new Book[1]; 
        Book[] books2 = new Book[1]; 
        Book book = new Book(); 
        books1[0] = book; 
        books2[0] = book; 
        System.out.println("compare object array = " + (books1.equals(books2))); 
        System.out.println("compare object arrays= " + Arrays.equals(books1, books2)); 
    }    
  
    static class Book { 
  
        @Override 
        public boolean equals(Object obj) { 
            return true; 
        } 
  
        @Override 
        public int hashCode() { 
            return 1; 
        } 
  
    } 
} 

import java.util.Arrays;
 
 
public class ArrayCompareRoot {
 public static void main(String[] args) {
  final String s = "Google";
  byte[] content1 = s.getBytes();
  byte[] content2 = s.getBytes();
  compareAddress(content1, content2);
  compareContent(content1, content2);
  compare(content1, content2);
  compareObjectArrays();
 }
 
 private static final void compareAddress(byte[] value1, byte[] value2) {
  System.out.println("value1 compare value2 by address = " + (value1 == value2));
 }
 
 private static final void compareContent(byte[] value1, byte[] value2) {
  System.out.println("value1 commpare value2 by content = " + (value1.equals(value2)));
 }
 
 private static final void compare(byte[] value1, byte[] value2) {
  System.out.println("value1 compare value2 = " + Arrays.equals(value1, value2));
 }
 
 private static final void compareObjectArrays() {
  Book[] books1 = new Book[1];
  Book[] books2 = new Book[1];
  Book book = new Book();
  books1[0] = book;
  books2[0] = book;
  System.out.println("compare object array = " + (books1.equals(books2)));
  System.out.println("compare object arrays= " + Arrays.equals(books1, books2));
 } 
 
 static class Book {
 
  @Override
  public boolean equals(Object obj) {
   return true;
  }
 
  @Override
  public int hashCode() {
   return 1;
  }
 
 }
}

运行结果如下:
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方法内容如下:

public boolean equals(Object obj) { 
    return (this == obj); 
} 

public boolean equals(Object obj) {
 return (this == obj);
}

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

public static boolean equals(byte[] a, by