優(yōu)雅編程之這樣使用對象通用方法,你就“正?!绷耍ㄈ模?/h2>

開心一笑

【一對夫婦避孕失敗后生了一個小男孩,孩子一生出來就緊握拳頭,一直笑個不停.護士把他的拳頭一掰開.發(fā)現(xiàn)里面有一把避孕藥,接著小男孩開口說話了:“你們兩個想弄死我,沒那么容易,哈哈哈】

提出問題

項目開發(fā)中,對象都通用的方法要注意那些???

解決問題

勵志圖片
覆蓋equals時請遵守通用約定

先溫習下枯燥的理論知識,很無聊,但很重要。

  • 自反性:對于任何非null的引用值x,x.equals(x)必須返回true.
  • 對稱性:對于非空的引用值x,y,當且僅當x.equals(y)返回true時,y.equals(x)必須返回true.
  • 傳遞性:對于任何非null的引用值x,y,z,如果x.equals(y)=true,y.equals(z)=true,那么x.equals(z)也必須返回true。
  • 一致性:對于任何非null的引用值x,y,只要equals的比較操作在對象中所用的信息沒有被修改,多次調用x.equals(y)就會一致地返回true,或一致地返回false.
  • 對于非null的引用值x,x.equals(null)必須返回false.

高質量equals方法的訣竅

  1. 使用==操作符檢查參數(shù)是否為這個對象的引用。
  2. 使用instanceof操作符檢查參數(shù)是否為正確的類型。
  3. 把參數(shù)轉換成正確的類型。
  4. 當編寫完成了equals方法之后,應該問自己三個問題,它是否是對稱的、傳遞的、一致的。

我用開發(fā)工具自動幫我生成equals方法:

@Override
public boolean equals(Object o) {
    //使用==操作符檢查參數(shù)是否為這個對象的引用
    if (this == o) return true;
    //使用instanceof操作符檢查參數(shù)是否為正確的類型
    if (!(o instanceof AyTest)) return false;
    //把參數(shù)轉換成正確的類型
    AyTest ayTest = (AyTest) o;
    
    if (flowerNum != ayTest.flowerNum) return false;

    return true;
}
覆蓋equals時總要覆蓋hashCode

覆蓋equals方法,必須覆蓋hashCode方法。如果不這樣做,就會違反Object.hashCode的通用約定,從而也導致該類無法結合所有基于散列的結合一塊正常運轉,這樣的結合包括HashMap、HashSet和Hashtable

//這里引用課本的例子,非原創(chuàng)
public final class PhoneNumber {  

    private final short areaCode;        
    private final short prefix;     
    private final short lineNumber;  
      
    public PhoneNumber(int areaCode, int prefix, int lineNumber) {  
        rangeCheck(areaCode, 999,  "area code");  
        rangeCheck(prefix, 999,  "prefix");  
        rangeCheck(lineNumber, 9999,  "line number");  
          
        this.areaCode = (short)areaCode;  
        this.prefix = (short)prefix;  
        this.lineNumber = (short)lineNumber;  
    }  
      
    private static void rangeCheck(int arg, int max, String name) {  
        if (arg < 0 || arg > max) {  
            throw new IllegalArgumentException(name + ": " + arg);  
        }  
    }  
      
    @Override  
    public boolean equals(Object o) {  
        if (o == this) {  
            return true;  
        }   
        if (!(o instanceof PhoneNumber)) {  
            return false;  
        }    
        PhoneNumber pNumber = (PhoneNumber)o;   
        return (pNumber.lineNumber == lineNumber) && (pNumber.prefix == prefix) && (pNumber.areaCode == areaCode);  
    }  
}  

測試例子:

public static void hashCodePhoneNumber() {  
    Map<PhoneNumber, String> map = new HashMap<PhoneNumber, String>();  
    PhoneNumber phoneNumber = new PhoneNumber(707, 867, 9876);  
    map.put(phoneNumber, "Jenny");
    //這里是重點 重點 重點  一個是new 出來的 一個是 原來的phoneNumber    
    System.out.println(map.get(new PhoneNumber(707, 867, 9876)));  
    System.out.println(map.get(phoneNumber));  
} 

執(zhí)行結果:

null    
Jenny   

解釋一下:

不去覆蓋hashCode,使用map.put時,我們是把這些PhoneNumber對象放在各個不同的盒子里,而我們去map.get()的時候,只是去某一個盒子里去找,而如果我們覆蓋了hashCode方法,這時,如果通過hashCode計算出來的值是相等的,就會放在同一個盒子里。這樣,只要我們對象中保存的值是完全一致的,就會找到這個key所對應的value。

始終要覆蓋toString

如果我們不覆蓋類的toString()方法,后果可能是當我們需要去打印這個類的對象時,會有一些并非是我們想要的那種結果。現(xiàn)在開發(fā)工具很方便,可以使用開發(fā)工具自動幫助我們生成。

謹慎的覆蓋clone

拷貝的含義是:

  • x.clone() != x
  • x.clone().getClass() == x.getClass()
  • x.clone().equals(x)

覆蓋clone方法要非常小心,如果類里面含有復雜數(shù)據(jù)類型,要進行深度復制,如果類里面有final屬性,則無法進行clone,因為final屬性在clone時無法再進行賦值。

最好呢就是別去覆蓋這個方法,需要復制的話可以使用拷貝構造器和靜態(tài)拷貝工廠

考慮實現(xiàn)Comparable接口
  • comparaTo方法不是Object中的方法,而是Comparable接口中唯一的方法。該方法不僅可進行等同性比較,還可以進行順序比較。

  • 接口的通用約定是按照equals方法來定義的,但有序集合使用了compareTo方法的等同性測試。

  • 如果是是一個值類,而且具有明顯的內在排序關系,就因該堅決實現(xiàn)該接口。

  • 如果你正在編寫一個值類,它具有非常明顯的內在排序關系,比如按字母順序、按數(shù)值順序或者按照年代順序,那就應該堅決考慮實現(xiàn)這個接口。

參考文章

【1】Effective Java:對于所有對象都通用的方法
【2】Java中equals和==的區(qū)別
【3】Effective Java——對所有對象通用的方法
【4】Effective Java 讀書筆記之二 對于所有對象都通用的方法
【5】考慮實現(xiàn)Comparable接口

讀書感悟

來自韓寒《我所理解的生活》

  • 我所理解的生活就是做著自己喜歡的事情,養(yǎng)活自己,養(yǎng)活家人。生活不是攀爬高山,也不是深潛海溝,它只是在一張標配的床上睡出你的身形。我所理解的生活就是和自己喜歡的一切在一起。
  • 緣分不是走在街上非要撞見,緣分就是睡前醒后彼此想念。
  • 打死也不能放棄,窮死也不能嘆氣,要讓笑話你的人成為笑話。
  • 可以后悔,但不留遺憾,有很多事情做了以后發(fā)現(xiàn)自己傻了或者失敗了,但還是要去做。
  • 世間萬千種寵愛,無數(shù)種人心,得之我幸,不得我也沒什么不幸。
  • 我相信真誠相待,也相信倒霉認栽。
  • 每個人的道路都不同,我走在我的野路上,她走在她的大路上,都值得祝福。只要不走歪路邪路,每條道路都有成功的方式。

其他

如果有帶給你一絲絲小快樂,就讓快樂繼續(xù)傳遞下去,歡迎轉載,點贊,頂,歡迎留下寶貴的意見,多謝支持!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容