優雅にプログラミングするこのようにオブジェクトの共通の方法を使うと、あなたは「正常」になります(三十四)


嬉しそうに笑う
【夫婦が避妊に失敗して男の子を産んだ.子供は一生出てきてこぶしを握りしめて、ずっと笑っていた.看護婦はこぶしを割った.中に避妊薬が入っているのを見つけて、男の子は口を開いた.「あなたたち二人は私を殺そうとしたが、そんなに簡単ではない.ハハハ」
質問**
プロジェクト开発において、対象に対して通用する方法はどれらに注意しますか??
問題を解決する
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メソッドのコツ
  • ==オペレータを使用して、パラメータがこのオブジェクトの参照であるかどうかを確認します.
  • instanceofオペレータを使用して、パラメータが正しいタイプであるかどうかを確認します.
  • パラメータを正しいタイプに変換します.
  • equalsメソッドの作成が完了した後、対称的、伝達的、一致しているかどうかの3つの質問を自分に聞かなければならない.

  • 開発ツールを使用してequalsメソッドを自動的に生成します.
    @Override
    public boolean equals(Object o) {
        //  ==                 
        if (this == o) return true;
        //  instanceof               
        if (!(o instanceof AyTest)) return false;
        //           
        AyTest ayTest = (AyTest) o;
    
        if (flowerNum != ayTest.flowerNum) return false;
    
        return true;
    }
    

    equalsを上書きする場合はhashCodeを上書きします
    equalsメソッドを上書きするにはhashCodeメソッドを上書きする必要があります.そうしないとObjectに違反します.hashCodeの一般的な規則は、クラスがハッシュベースのすべての結合を結合して正常に動作しないことをもたらす.このような結合には、HashMap、HashSet、Hashtableが含まれる.
    //         ,   
    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));  
    } 
    

    実行結果:
    null    
    Jenny   
    

    説明します.
    hashCodeを上書きせずmapを使用する.putの時、私たちはこれらのPhoneNumberオブジェクトをそれぞれの箱に入れて、mapに行きます.get()の場合、ある箱に行って探すだけで、hashCodeメソッドを上書きした場合、hashCodeで計算した値が等しい場合は、同じ箱に入れます.これにより、オブジェクトに保存されている値が完全に一致している限り、このkeyに対応するvalueが見つかります.
    常にtoStringを上書きする
    クラスのtoString()メソッドを上書きしないと、このクラスのオブジェクトを印刷する必要がある場合、私たちが望んでいない結果がある可能性があります.開発ツールは便利で、開発ツールを使用して自動的に生成することができます.
    慎重なカバーclone
    コピーの意味は次のとおりです.
  • x.clone() != x
  • x.clone().getClass() == x.getClass()
  • x.clone().equals(x)

  • cloneメソッドを上書きするには、クラスに複雑なデータ型が含まれている場合は、深くコピーし、クラスにfinal属性がある場合はcloneを実行できません.final属性はclone時に付与できないためです.
    この方法を上書きしないで、コピーが必要な場合はコピーコンストラクタと静的コピーファクトリを使用することができます.
    Comparableインタフェースの実装を検討
  • comparaToメソッドはObjectのメソッドではなく、Comparableインタフェースの唯一のメソッドです.この方法は等同性比較だけでなく,順序比較も可能である.
  • インタフェースの一般的な規則はequalsメソッドに従って定義されるが,秩序化集合はcompareToメソッドの等性テストを用いた.
  • が値クラスであり、明らかな内在的なソート関係を有する場合、インタフェースは断固として実現される.
  • 値クラスを作成している場合は、アルファベット順、数値順、年代順など、非常に明らかな内在的なソート関係を持っている場合は、このインタフェースの実現を断固として考慮する必要があります.

  • 参考記事
    【1】Effective Java:すべてのオブジェクトに共通する方法
    【2】Javaにおけるequalsと==の違い
    【3】Effective Java――すべてのオブジェクトに共通する方法
    【4】Effective Java読書ノートその2すべての対象に共通する方法
    【5】Comparableインタフェースの実装を検討
    本を読んで悟る.
    韓寒の「私が理解している生活」から
  • 私が理解している生活は、自分の好きなことをして、自分を養って、家族を養うことです.生活は高い山に登るのではなく、深い溝に潜るのではなく、標準的なベッドであなたの体の形を寝ているだけです.私が理解している生活は自分の好きなすべてと一緒にいることです.
  • 縁は街を歩いているのではなく、縁は寝る前に目が覚めてからお互いを懐かしむことだ.
  • 死んでもあきらめてはいけない.貧乏で死んでもため息をつくことはできない.冗談を言っている人を冗談にしなければならない.
  • は後悔することができますが、残念なことではありません.自分が馬鹿になったり失敗したりしたことに気づいたことがたくさんありますが、やはりしなければなりません.
  • 世の万千の寵愛、無数の人の心、得た私は幸いで、私も不幸ではありません.
  • 私は誠実に接していると信じて、運が悪いと信じています.
  • すべての人の道はすべて異なって、私は私の野道を歩いて、彼女は彼女の大通りを歩いて、すべて祝福に値します.邪道を歩かない限り、どの道にも成功の方法がある.

  • その他
    もしあなたに少しの楽しみを持ってきたら、楽しみを伝え続けて、転載を歓迎して、いいね、トップ、貴重な意見を残して、支持に感謝します!