posts - 28,  comments - 15,  trackbacks - 0
              使用java的人都知道,如果覆蓋了Object的equals方法,那么必須要覆蓋hashCode方法,并且如果兩個對象用equals方法比較返回true,那么這兩個對象hashCode返回的值也必須是相等的,并且對于同一個對象,equals方法需要比較的屬性值沒有被修改,那么每次調(diào)用hashCode返回的值應(yīng)該是一致的。
              那么為什么需要這樣呢,是不是所有的對象在覆蓋Object的equal方法時都需要覆蓋hashCode方法呢?下面以一個實例來說明該問題:
           public class HashTest
          {
              @Test
              
          public void testEqualAndHash()
              
          {
                  
                  Map
          <HashObject, String> map = new HashMap<HashObject, String>();
                  
          for(int i = 0; i < 10; i++)
                  
          {
                      HashObject o 
          = new HashObject();
                      o.setId(i);
                      o.setIdCard(
          "id_" + i);
                      o.setName(
          "name_" + i);
                      o.setAddress(
          "address_" + i);
                      
                      map.put(o, o.getName());
                      System.out.println();
                  }

                  
                  HashObject o 
          = new HashObject();
                  o.setId(
          0);
                  o.setIdCard(
          "id_" + 0);
                  o.setName(
          "name_" + "zhangsan");
                  String v 
          = map.put(o, o.getName());
                  
          /* 未實現(xiàn)hashcode方法,調(diào)用map的put方法將不會返回舊值,而是返回null */
                  System.out.println(
          "v:" + v);
                  System.out.println(
          "size:" + map.size());
              }

          }


          public class HashObject
          {
              
          private Integer id;
              
              
          private String name;
              
              
          private String idCard;
              
              
          private String address;
              
              
          public Integer getId()
              
          {
                  
          return id;
              }

              
              
          public void setId(Integer id)
              
          {
                  
          this.id = id;
              }

              
              
          public String getName()
              
          {
                  
          return name;
              }

              
              
          public void setName(String name)
              
          {
                  
          this.name = name;
              }

              
              
          public String getIdCard()
              
          {
                  
          return idCard;
              }

              
              
          public void setIdCard(String idCard)
              
          {
                  
          this.idCard = idCard;
              }

              
              
          public String getAddress()
              
          {
                  
          return address;
              }

              
              Object o 
          = null;
              
              
          public void setAddress(String address)
              
          {
                  
          this.address = address;
              }

              
              
          public boolean equals(Object o)
              
          {
                  
                  
          if(this == o)
                      
          return true;
                  
                  HashObject x 
          = (HashObject) o;
                  
          if(x.getIdCard().equals(this.idCard))
                      
          return true;
                  
           
                 return false;
                  
              }

              
              
          // public int hashCode()
              
          // {
              
          //
              
          // return 17 * 37 + this.idCard.hashCode();
              
          //
              
          // }
          }

          關(guān)閉與開啟HashObject的hashCode方法的執(zhí)行結(jié)果
          v:null
          size:11
          ----------------------
          v:name_0
          size:10

          那么為什么會這樣呢,讓我們看看
           1public V put(K key, V value) {
           2        if (key == null)
           3            return putForNullKey(value);
           4        /*對key的hashcode做hash運算*/
           5        int hash = hash(key.hashCode());
           6        /*獲得key對應(yīng)的Entry的索引位置*/
           7        int i = indexFor(hash, table.length);
           8        for (Entry<K,V> e = table[i]; e != null; e = e.next) {
           9            Object k;
          10            /*HashMap采用鏈表來解決hashcode沖突,從這里可以看出,只有hashcode相等,且equals或者地址相等,HashMap才認(rèn)為對象是相同的*/
          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
          19        modCount++;
          20        addEntry(hash, key, value, i);
          21        return null;
          22    }
          HashMap的實現(xiàn)就一目了然了。HashMap采用Entry數(shù)組作為存儲<key,value>的數(shù)據(jù)結(jié)構(gòu),數(shù)組的索引是同過對key的hashcode做hash運算獲得的,HashMap采用鏈表來解決hash沖突問題。下面讓我們看看HashMap的put方法實現(xiàn):


          posted on 2012-08-16 18:39 zhangxl 閱讀(431) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
          <2012年8月>
          2930311234
          567891011
          12131415161718
          19202122232425
          2627282930311
          2345678

          常用鏈接

          留言簿(1)

          隨筆分類(17)

          隨筆檔案(28)

          文章分類(30)

          文章檔案(30)

          相冊

          收藏夾(2)

          hibernate

          java基礎(chǔ)

          mysql

          xml

          關(guān)注

          壓力測試

          算法

          最新隨筆

          搜索

          •  

          積分與排名

          • 積分 - 96750
          • 排名 - 600

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 吉安市| 磐石市| 比如县| 肥东县| 原阳县| 溆浦县| 梁河县| 晋宁县| 吕梁市| 临汾市| 莱阳市| 松滋市| 邹平县| 永兴县| 临安市| 三门县| 沧州市| 翼城县| 湾仔区| 九龙县| 洛宁县| 招远市| 射阳县| 西贡区| 郎溪县| 东阳市| 正宁县| 永新县| 皮山县| 赣榆县| 乌鲁木齐市| 黄浦区| 从江县| 修文县| 温州市| 武夷山市| 临澧县| 凤凰县| 白银市| 闻喜县| 鸡西市|