hashCode() 和 equals()比较

1. 首先equals()和hashCode()这两个方法都是从Object类中继承过来的。

equals()方法在Object类中定义如下:

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

很明显是对两个对象的地址值进行的比较(即比较引用是否相同)。但是我们必需清楚,当String 、Math、Integer、Double等这些封装类在使用equals()方法时,已经覆盖了Object类的equals()方法。

比如在String类中如下:

 1 public boolean equals(Object anObject) {
 2     if (this == anObject) {
 3         return true;
 4     }
 5     if (anObject instanceof String) {
 6         String anotherString = (String) anObject;
 7         int n = value.length;
 8         if (n == anotherString.value.length) {
 9             char v1[] = value;
10             char v2[] = anotherString.value;
11             int i = 0;
12             while (n-- != 0) {
13                 if (v1[i] != v2[i])
14                     return false;
15                  i++;
16             }
17             return true;
18         }
19     }
20     return false;
21 }                                

这是进行的内容比较,而已经不再是地址的比较。依次类推Double、Integer、Math。。。。等等这些类都是重写了equals()方法的,从而进行的是内容的比较。当然了基本类型是进行值的比较,这个没有什么好说的。

 

2. 其次是hashCode() 方法,在Object类中定义如下:

public native int hashCode();

说明hashcode是一个本地方法,它的实现是根据本地机器相关的。当然我们可以在自己写的类中覆盖hashcode()方法,比如String、Integer、Double。。。。等等这些类都是覆盖了hashCode()方法的。

例如在String类中定义的hashcode()方法如下:

 1 public int hashCode() {
 2     int h = hash;
 3     if (h == 0 && value.length > 0) {
 4         char val[] = value;
 5         for (int i = 0; i < value.length; i++) {
 6             h = 31 * h + val[i];
 7         }
 8         hash = h;
 9     }
10     return h;
11 }        

3. 这里我们需要明白问题:

  • equals()相等的两个对象,hashCode()一定相等。

  • equals()不相等的两个对象,却并不能证明他们的hashcode()不相等。换句话说,equals()方法不相等的两个对象,hashcode()有可能相等。(我的理解是由于哈希码在生成的时候产生冲突造成的)。

  • hashCode()不等,一定能推出equals()也不等。

4. 集合中的表现

比如HashSet,里面存储的对象不能相同,但是这个不能相同怎么来定义,查看其源码可以发现:

 1 public V put(K key, V value) {
 2     if (table == EMPTY_TABLE) {
 3         inflateTable(threshold);
 4     }
 5     if (key == null)
 6         return putForNullKey(value);
 7     int hash = hash(key);
 8     int i = indexFor(hash, table.length);
 9     for (Entry<K,V> e = table[i]; e != null; e = e.next) {
10          Object k;
11          if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
12              V oldValue = e.value;
13              e.value = value;
14              e.recordAccess(this);
15              return oldValue;
16           }
17     }
18     modCount++;
19     addEntry(hash, key, value, i);
20     return null;
21 }    

 

其中的这一步:

e.hash == hash && ((k = e.key) == key || key.equals(k)) 

,先判断hash是否相同,在进行equals进行对比.

猜你喜欢

转载自www.cnblogs.com/itbuyixiaogong/p/9056290.html