<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Heis的Blog

    保持簡單,保持愚蠢
    隨筆 - 29, 文章 - 1, 評論 - 122, 引用 - 0
    數(shù)據(jù)加載中……

    大話深入淺出Effective Java核心實戰(zhàn)編程思想之——那些雞翅

        好吧好吧,我承認(rèn)這有點標(biāo)題黨的嫌疑,我這不是隔太久沒更新,有點興奮么。
        板磚拍夠了,臭雞蛋扔夠了,別來打醬油便行了。我這就進入正題。其實正確的標(biāo)題應(yīng)該叫Effective Java讀書心得之雞翅的故事。

        關(guān)于雞翅的故事,相傳最近最近以前……
     1 import static org.junit.Assert.*;
     2 
     3 import java.util.HashMap;
     4 
     5 import org.junit.Test;
     6 
     7 
     8 public class TestObjectHashCode {
     9     
    10     @Test
    11     public void testIt(){
    12           //最近,麥當(dāng)當(dāng)推出了麥香翅,味道不是一般的好,那是相當(dāng)?shù)暮谩?br /> 13           //于是受到消費者的青睞,大受歡迎。
    14           雞翅 麥香翅=new 雞翅("麥香翅");
    15           味道 味道好極了=new 味道("味道好極了");
    16           HashMap 市場=new HashMap();
    17           市場.put(麥香翅, 味道好極了);
    18           
    19           //這一切都被一個山寨小食店看在眼里,他們決定打著麥香翅的名號,推出實際上味道一般的山寨麥香翅
    20           雞翅 山寨麥香翅=new 雞翅("麥香翅");            
    21           
    22           //山寨小食店的師傅還是很有智慧的,他們通過某某方式,通過ISO叉叉叉叉的認(rèn)證。
    23           //他們很天真地認(rèn)為他們的山寨翅可以媲美麥香翅。
    24           assertTrue(山寨麥香翅.equals(麥香翅)); 
    25           
    26           //但是結(jié)果大家都知道了,山寨翅并沒有獲得市場的認(rèn)可,魚目混珠終究被市場識別出來。
    27           assertFalse(味道好極了.equals(市場.get(山寨麥香翅)));
    28           
    29           //山寨小食店苦思瞑想,終于發(fā)現(xiàn)了問題,原來他們指打相同的名號是不行的。
    30           //他們的并沒有山寨出麥香翅代號為HashCode的秘制醬料
    31           assertFalse(麥香翅.hashCode()==山寨麥香翅.hashCode());         
    32     }
    33     
    34     public static final class 味道{
    35           private String description;
    36 
    37           public 味道(String des){
    38                 description=des;
    39           }
    40           
    41           public String getDescription() {
    42                 return description;
    43           }
    44 
    45           public void setDescription(String aDes) {
    46                 this.description = aDes;
    47           }
    48           
    49     }
    50 
    51     public static final class 雞翅 {
    52 
    53         private String Name;
    54 
    55         public 雞翅(String name){
    56               this.Name=name;
    57         }
    58         
    59         public String getName() {
    60               return Name;
    61         }
    62 
    63         public void setName(String aName) {
    64               this.Name = aName;
    65         }
    66         
    67         @Override
    68         public boolean equals(Object obj){
    69               if(!(obj instanceof 雞翅)){
    70                     return false;
    71               }
    72               return ((雞翅)obj).getName().equals(this.Name);
    73         }
    74   }
    75 
    76 }
    77 
        看完了不知道我想說啥?看來沒認(rèn)真看《Effective Java》嘛,這本書可是每個java程序員進階必修之書,沒看過真不能自稱大蝦級別。好了,這里說到了正題的正題,其實我想說的是:

    《Effective Java》第八條:改寫equals時總是要改寫hashCode。


    *為什么要改寫hashCode
    答:(書上原話)“如果不這樣做的話,就會違反Object.hashCode的通用約定,從而導(dǎo)致該類無法與所有基于散列值(hash)的集合類在一起正常工作,這樣的集合類包括HashMap,HashSet和Hashtable.

    *那么為什么會導(dǎo)致該類無法與所有基于散列值(hash)的集合類在一起正常工作呢?
    答:且看一個HashMap的源代碼解釋。

    HashMap是通過一個叫table[]的數(shù)組來存取,table的每個元素是一個鏈表結(jié)構(gòu),鏈表的每個元素稱為 Entry<key,value>,是真正存放key和value的對象。在put的過程中,HashMap會通過特定的哈希算法將key對象的hashCode對應(yīng)到table的某個索引下,然后再用key對比鏈表中每個Entry.key,如果key相同則更新value。否則就加入新的 Entry到鏈表中。

    HashMap的數(shù)據(jù)結(jié)構(gòu)圖:




    再看一段HashMap的源代碼:
     1 public V put(K key, V value) {
     2     K k = maskNull(key);// 如果key為null則使用缺省的Object
     3         int hash = hash(k);//將k的hashCode經(jīng)過一定的計算得到新的HashCode
     4         int i = indexFor(hash, table.length);//取得HashCode在table中的位置
     5 
     6       //首先在數(shù)組內(nèi)根據(jù)key的HashCode找到Entry鏈表的第一個Entry        
     7         for (Entry<K,V> e = table[i]; e != null; e = e.next) {
     8         //如果Entry的key值HashCode相同,而且具有相同的引用或邏輯相等(equals)
     9             if (e.hash == hash && eq(k, e.key)) {
    10             //將新的value放入Entry中,返回舊的value
    11                 V oldValue = e.value;
    12                 e.value = value;
    13                 e.recordAccess(this);
    14                 return oldValue;
    15             }
    16         }
    17       
    18         //修改次數(shù)加1
    19         modCount++;
    20       //在table的第i個位置的鏈表后加上一個新的Entry
    21         addEntry(hash, k, value, i);
    22         return null;
    23 }
    24 
    25 static boolean eq(Object x, Object y) {
    26         return x == y || x.equals(y);
    27     }
    28 

    *最后來看java.lang.Object的約定(經(jīng)過自己語言描述,原話自己看書去)
    1.如果一個類的equals方法所用到的信息(邏輯相等的條件因素)沒有被修改的話,那么它hashCode也不會改變。換個角度來看,也就是說,hashCode返回值最好與equals方法所用到的信息相關(guān)。

    2.如果兩個實例根據(jù)equals對比是相等的,那么它們的HashCode相等。

    3.如果兩個實例根據(jù)equals對比是不相等的,那么它們的HashCode最好是不等,這對于Hash性能的提高有好處。

    E.g 如果Person實例的ID屬性沒有被修改的話,那么它的HashCode也不會改變
     1 public class Person{
     2         private String ID;
     3         public boolean equals(Object obj){
     4              if(!(obj instanceof Person)&& ((Person)obj).getID()!=null){
     5                 return false;
     6         }
     7             return ((Person)obj).getID().equals(this.ID);
     8         }
     9 
    10         public int hashCode(){
    11             if(ID==null){
    12                 return 23;
    13             }else{
    14                 return ID.hashCode();
    15             }
    16         }
    17         public String getID() {
    18             return ID;
    19         }
    20         public void setID(String id) {
    21             ID = id;
    22         }
    23         
    24 }
    25 


    程序員的一生其實可短暫了,這電腦一開一關(guān),一天過去了,嚎;電腦一開不關(guān),那就成服務(wù)器了,嚎……

    posted on 2009-06-20 00:59 Heis 閱讀(1692) 評論(0)  編輯  收藏 所屬分類: Effective Java

    主站蜘蛛池模板: 亚洲av无码电影网| 国产午夜不卡AV免费| 亚洲成av人片天堂网老年人| 国产99视频精品免费视频76| 色播亚洲视频在线观看| 成年性生交大片免费看| 精品久久久久久国产免费了| 亚洲伊人久久大香线蕉影院| 亚洲国产精品成人| h在线观看视频免费网站| 美女免费精品高清毛片在线视| 亚洲av永久无码制服河南实里| 成人a视频片在线观看免费| 99久久成人国产精品免费 | 久久精品亚洲一区二区三区浴池 | 亚洲一区二区三区在线视频| 67194国产精品免费观看| 在线观看亚洲免费视频| 精品亚洲A∨无码一区二区三区| 青青青国产色视频在线观看国产亚洲欧洲国产综合| 好男人资源在线WWW免费| 亚洲熟妇久久精品| 亚洲一区二区三区电影| 亚洲精品视频在线观看你懂的 | 亚洲短视频男人的影院| 国产99视频精品免费视频7| 麻豆高清免费国产一区| 一级a性色生活片久久无少妇一级婬片免费放| 亚洲欧洲国产综合| 国产精品亚洲精品日韩已满| 国产亚洲精品免费| 18禁无遮挡无码网站免费| 日本不卡免费新一区二区三区| 农村寡妇一级毛片免费看视频 | 黄色一级免费网站| 自拍偷区亚洲国内自拍| 亚洲综合色丁香麻豆| 国产AV无码专区亚洲精品| 亚洲国产人成中文幕一级二级| 麻豆国产入口在线观看免费| 国产成人免费在线|