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进行对比.

  • 相关阅读:
    Ubuntu下一个openldapserver部署步骤
    秀球技:倒和其他无用
    POJ1201-Intervals(差动限制)
    Scrapy研究和探索(七)——如何防止被ban大集合策略
    word 一些有用的技巧
    Java设计模式偷跑系列(十二)组合模式建模和实现
    Sql使用视图(简单的视图)适合入门-level
    cocos2d 缓存池 对象的再利用
    txt 开关 csv 可通用 工具
    使用SharePoint创建和定义自己的网站页面
  • 原文地址:https://www.cnblogs.com/itbuyixiaogong/p/9056290.html
Copyright © 2011-2022 走看看