<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)編程思想之——那些雞翅

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

        關于雞翅的故事,相傳最近最近以前……
     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           //最近,麥當當推出了麥香翅,味道不是一般的好,那是相當?shù)暮谩?br /> 13           //于是受到消費者的青睞,大受歡迎。
    14           雞翅 麥香翅=new 雞翅("麥香翅");
    15           味道 味道好極了=new 味道("味道好極了");
    16           HashMap 市場=new HashMap();
    17           市場.put(麥香翅, 味道好極了);
    18           
    19           //這一切都被一個山寨小食店看在眼里,他們決定打著麥香翅的名號,推出實際上味道一般的山寨麥香翅
    20           雞翅 山寨麥香翅=new 雞翅("麥香翅");            
    21           
    22           //山寨小食店的師傅還是很有智慧的,他們通過某某方式,通過ISO叉叉叉叉的認證。
    23           //他們很天真地認為他們的山寨翅可以媲美麥香翅。
    24           assertTrue(山寨麥香翅.equals(麥香翅)); 
    25           
    26           //但是結果大家都知道了,山寨翅并沒有獲得市場的認可,魚目混珠終究被市場識別出來。
    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 
        看完了不知道我想說啥?看來沒認真看《Effective Java》嘛,這本書可是每個java程序員進階必修之書,沒看過真不能自稱大蝦級別。好了,這里說到了正題的正題,其實我想說的是:

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


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

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

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

    HashMap的數(shù)據(jù)結構圖:




    再看一段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方法所用到的信息相關。

    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 


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

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

    主站蜘蛛池模板: 国产男女猛烈无遮档免费视频网站 | 国产V亚洲V天堂无码久久久| 看亚洲a级一级毛片| 狼友av永久网站免费观看| 亚洲一线产区二线产区精华| 又粗又大又黑又长的免费视频| 久久久久久亚洲Av无码精品专口| 免费精品无码AV片在线观看| 亚洲第一永久在线观看| 1000部拍拍拍18免费网站| 亚洲电影一区二区| 久久爰www免费人成| 亚洲国产日韩在线一区| 最近2019中文字幕免费看最新| 亚洲av成人一区二区三区观看在线| 国产一卡2卡3卡4卡无卡免费视频| 日韩亚洲产在线观看| 免费a级毛片在线观看| 午夜成人无码福利免费视频| 亚洲人成网站在线观看播放| 2019中文字幕免费电影在线播放| 中文字幕无码精品亚洲资源网久久 | 亚洲色图校园春色| 免费黄色app网站| www免费黄色网| 亚洲视频在线观看不卡| 午夜两性色视频免费网站| fc2免费人成在线| 亚洲精品美女久久久久| 日本成人在线免费观看| 中文字幕免费在线播放| 亚洲国产成AV人天堂无码| 免费看国产一级特黄aa大片| 最近中文字幕大全免费版在线 | 亚洲AV无码成人精品区日韩| 一本天堂ⅴ无码亚洲道久久| 亚洲AV日韩AV永久无码色欲| 亚洲精品成人网久久久久久| 麻豆成人久久精品二区三区免费 | 亚洲国产精品成人| 久久国产乱子免费精品|