posts - 28,  comments - 15,  trackbacks - 0
              使用java的人都知道,如果覆蓋了Object的equals方法,那么必須要覆蓋hashCode方法,并且如果兩個(gè)對(duì)象用equals方法比較返回true,那么這兩個(gè)對(duì)象hashCode返回的值也必須是相等的,并且對(duì)于同一個(gè)對(duì)象,equals方法需要比較的屬性值沒有被修改,那么每次調(diào)用hashCode返回的值應(yīng)該是一致的。
              那么為什么需要這樣呢,是不是所有的對(duì)象在覆蓋Object的equal方法時(shí)都需要覆蓋hashCode方法呢?下面以一個(gè)實(shí)例來說明該問題:
           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());
                  
          /* 未實(shí)現(xiàn)hashcode方法,調(diào)用map的put方法將不會(huì)返回舊值,而是返回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

          那么為什么會(huì)這樣呢,讓我們看看
           1public V put(K key, V value) {
           2        if (key == null)
           3            return putForNullKey(value);
           4        /*對(duì)key的hashcode做hash運(yùn)算*/
           5        int hash = hash(key.hashCode());
           6        /*獲得key對(duì)應(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)為對(duì)象是相同的*/
          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的實(shí)現(xiàn)就一目了然了。HashMap采用Entry數(shù)組作為存儲(chǔ)<key,value>的數(shù)據(jù)結(jié)構(gòu),數(shù)組的索引是同過對(duì)key的hashcode做hash運(yùn)算獲得的,HashMap采用鏈表來解決hash沖突問題。下面讓我們看看HashMap的put方法實(shí)現(xiàn):


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

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


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

          常用鏈接

          留言簿(1)

          隨筆分類(17)

          隨筆檔案(28)

          文章分類(30)

          文章檔案(30)

          相冊(cè)

          收藏夾(2)

          hibernate

          java基礎(chǔ)

          mysql

          xml

          關(guān)注

          壓力測(cè)試

          算法

          最新隨筆

          搜索

          •  

          積分與排名

          • 積分 - 96363
          • 排名 - 601

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 儋州市| 苏尼特右旗| 邓州市| 布拖县| 含山县| 新竹县| 安化县| 察隅县| 阳朔县| 紫金县| 德惠市| 台东市| 会东县| 龙江县| 墨脱县| 孝昌县| 永登县| 平邑县| 神木县| 大庆市| 凤山县| 江华| 莱阳市| 万山特区| 如东县| 佛山市| 临夏县| 营口市| 兴宁市| 五指山市| 拉孜县| 永善县| 腾冲县| 荣昌县| 富源县| 资兴市| 鱼台县| 阜南县| 明溪县| 崇信县| 晴隆县|