zoukankan      html  css  js  c++  java
  • 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进行对比.

  • 相关阅读:
    Codeforces Round #610 (Div. 2)C(贪心,思维)
    Educational Codeforces Round 80 (Rated for Div. 2)C(DP)
    BZOJ2190 仪仗队
    BZOJ3613 南园满地堆轻絮
    BZOJ1084 最大子矩阵
    BZOJ1036 树的统计Count
    BZOJ1452 Count
    BZOJ2242 计算器
    BZOJ2705 Longge的问题
    BZOJ1509 逃学的小孩
  • 原文地址:https://www.cnblogs.com/itbuyixiaogong/p/9056290.html
Copyright © 2011-2022 走看看