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

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

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

    小菜毛毛技術(shù)分享

    與大家共同成長

      BlogJava :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
      164 Posts :: 141 Stories :: 94 Comments :: 0 Trackbacks
    經(jīng)常在論壇上面看到覆寫hashCode函數(shù)的問題,很多情況下是一些開發(fā)者不了解hash code,或者和equals一起用的時候不太清楚為啥一定要復(fù)寫hashCode。

        對于hash code的理論我不想多說,這個話題太大。我只想說用hash code的原因只有一個:效率。理論的說法它的復(fù)雜度只有O(1)。試想我們把元素放在線性表里面,每次要找一個元素必須從頭一個一個的找它的復(fù)雜度有O(n)。如果放在平衡二叉樹,復(fù)雜度也有O(log n)。

       為啥很多地方說“覆寫equals的時候一定要覆寫hashCode”。說到這里我知道很多人知道有個原則:如果a.equals(b)那么要確保a.hashCode()==b.hashCode()。為什么?hashCode和我寫的程序的業(yè)務(wù)邏輯毫無關(guān)系,為啥我要override? 要我說如果你的class永遠(yuǎn)不可能放在hash code為基礎(chǔ)的容器內(nèi),不必勞神,您真的不必override hashCode() :)

        說得準(zhǔn)確一點(diǎn)放在HashMap和Hashtable里面如果是作為value而不是作為key的話也是不必override hashCode了。至于HashSet,實(shí)際上它只是忽略value的HashMap,每次HashSet.add(o)其實(shí)就是 HashMap.put(o, dummyObject)。

        那為什么放到Hash容器里面要overide hashCode呢?因?yàn)槊看蝕et的時候HashMap既要看equals是不是true也要看hash code是不是一致,put的時候也是要看equals和hash code。

        如果說到這里您還是不太明白,咱就舉個例子:

        譬如把一個自己定義的class Foo{...}放到HashMap。實(shí)際上HashMap也是把數(shù)據(jù)存在一個數(shù)組里面,所以在put函數(shù)里面,HashMap會調(diào) Foo.hashCode()算出作為這個元素在數(shù)組里面的下標(biāo),然后把key和value封裝成一個對象放到數(shù)組。等一下,萬一2個對象算出來的 hash code一樣怎么辦?會不會沖掉?先回答第2個問題,會不會沖掉就要看Foo.equals()了,如果equals()也是true那就要沖掉了。萬一 是false,就是所謂的collision了。當(dāng)2個元素hashCode一樣但是equals為false的時候,那個HashMap里面的數(shù)組的這 個元素就變成了鏈表。也就是hash code一樣的元素在一個鏈表里面,鏈表的頭在那個數(shù)組里面。

    回過來說get的時候,HashMap也先調(diào)key.hashCode()算出數(shù)組下標(biāo),然后看equals是不是true,所以就涉及了equals。

        反觀假設(shè)如果a.equals(b)但是a.hashCode()!=b.hashCode()的話,在put元素a之后,我們又用一個 a.equals(b)但是b.hashCode()!=a.hashCode()的b元素作為key來get的時候就找不到a了。如果 a.hashCode()==b.hashCode()但是!a.equals(b)倒是不要緊,這2個元素會collision然后被放到鏈表,只是效 率變差。

      這里有個非常簡化版的HashMap實(shí)現(xiàn)幫助大家理解。

    1. /* 
    2.  * Just to demonstrate hash map mechanism,  
    3.  * Please do not use it in your commercial product. 
    4.  * 
    5.  * @author Shengyuan Lu 盧聲遠(yuǎn) <michaellufhl@yahoo.com.cn> 
    6.  */  
    7. public class SimpleHashMap {  
    8.     ArrayList<LinkedList<Entry>> entries = new ArrayList<LinkedList<Entry>>();  
    9.       
    10.     /** 
    11.      * Each key-value is encapsulated by Entry. 
    12.      */  
    13.     static class Entry {  
    14.         Object key;  
    15.         Object value;  
    16.         public Entry(Object key, Object value) {  
    17.             this.key = key;  
    18.             this.value = value;  
    19.         }  
    20.     }  
    21.     void put(Object key, Object value) {  
    22.         LinkedList<Entry> e = entries.get(key.hashCode());  
    23.         if (e != null) {  
    24.             for (Entry entry : e) {  
    25.                 if (entry.key.equals(key)) {  
    26.                     entry.value = value;// Match in lined list  
    27.                     return;  
    28.                 }  
    29.             }  
    30.             e.addFirst(new Entry(key, value));// Add the entry to the list  
    31.         } else {  
    32.             // Put the new entry in array  
    33.             LinkedList<Entry> newEntry = new LinkedList<Entry>();  
    34.             newEntry.add(new Entry(key, value));  
    35.             entries.add(key.hashCode(), newEntry);  
    36.         }  
    37.     }  
    38.     Object get(Object key) {  
    39.         LinkedList<Entry> e = entries.get(key.hashCode());  
    40.         if (e != null) {  
    41.             for (Entry entry : e) {  
    42.                 if (entry.key.equals(key)) {  
    43.                     return entry.value;  
    44.                 }  
    45.             }  
    46.         }  
    47.         return null;  
    48.     }  
    49.       
    50.     /** 
    51.      * Do we need to override equals() and hashCode() for SimpleHashMap itself?  
    52.      * I don't know either:) 
    53.      */  
    54. }  


    這個問題的權(quán)威闡釋可以參考Bloch的<Effective Java>的 Item 9: Always override hashCode when you override equals

    posted on 2010-08-27 09:51 小菜毛毛 閱讀(396) 評論(0)  編輯  收藏 所屬分類: 面試
    主站蜘蛛池模板: 久久青草国产免费观看| 国产成人啪精品视频免费网| 视频免费1区二区三区| 亚洲一区二区三区久久| 亚洲Av综合色区无码专区桃色| 国产成人精品免费直播| 无码免费午夜福利片在线| 日本免费人成网ww555在线| 一级毛片高清免费播放| 色五月五月丁香亚洲综合网| 亚洲国产高清视频| 国产亚洲精品a在线观看| 免费少妇a级毛片| 在线永久免费观看黄网站| 久久精品网站免费观看| 日本最新免费网站| 最近中文字幕国语免费完整 | 亚洲精品免费在线视频| 国内精品免费视频精选在线观看| 免费人成网站永久| 国产一区二区三区亚洲综合| 亚洲aⅴ无码专区在线观看春色 | 免费黄色电影在线观看| 成人网站免费大全日韩国产| 一级成人毛片免费观看| 免费无码午夜福利片| 深夜免费在线视频| 午夜不卡AV免费| h视频在线免费观看| 一区在线免费观看| 中文字幕久无码免费久久| 国产在线精品一区免费香蕉| 成人免费av一区二区三区| 久久福利青草精品资源站免费 | 中文字幕亚洲日本岛国片| 国产亚洲色婷婷久久99精品91| 超清首页国产亚洲丝袜| 亚洲最大AV网站在线观看| 亚洲国产精品福利片在线观看 | 在线免费观看亚洲| 久久久久久久免费视频|