equalsの書き換えとhashmap

5264 ワード

equalsの書き換え
まず、equalsはobject類の方法であり、equalsメソッドを書き換えていないすべての種類の中で、方法の比較はすべて住所(引用)であり、つまり'=='と同じで、equalsメソッドを書き換えた種類は書き換えの方法で比較して、例えばString類はこの方法を書き直して、比較は内容です。
  • equals()equalsはルートのobjectの中の方法のソースコードです。
    public boolean equals(Object obj) {
        return (this == obj);
    }
    表示されるデフォルトのequalsメソッドは、直接に==を呼び出し、オブジェクトアドレスを比較します。異なるサブクラスでは、この方法を書き換えて、2つのオブジェクトのequalsの判断を行うことができます。
    Stringのソースコードの中の書き換えのequals方法は以下の通りです。
    public boolean equals(Object anObject) {
            if (this == anObject) {
                return true; //         
            }
            if (anObject instanceof String) {
                String anotherString = (String) anObject;
                int n = value.length;
                if (n == anotherString.value.length) {
                    char v1[] = value;
                    char v2[] = anotherString.value;
                    int i = 0;
                    while (n-- != 0) {
                        if (v1[i] != v2[i])
                                return false;
                        i++;
                    }
                    return true;
                 }
            }
            return false;
        }
    Stringクラスで書き換えられたequals()方法では、(1)まず比較したのは2つのオブジェクトの参照アドレスであり、比較対象が同一のオブジェクトの参照であれば、trueに戻ることがわかる。2)両者の参照が等しくない場合、二つの文字列オブジェクト内の文字を一つずつ比較し、等しい場合はtrueに戻す。
    hashmap
    デフォルトでは、ObjectのhashCode()は対象の32ビットjvmメモリアドレスに戻ります。つまり、オブジェクトがこの方法を書き換えないと、対応するオブジェクトの32がJVMメモリアドレスに戻る。 
    public int hashCode() {
        int h = hash;    //Default to 0 ### String       ,
        if (h == 0 && value.length > 0) {    
        //private final char value[]; ### Sting              
            char val[] = value;
    
            for (int i = 0; i < value.length; i++) {
                h = 31 * h + val[i];
            }
            hash = h;
        }
        return h;
    }
    Stringソースの中でprvate final char valueを使用します。文字列の内容を保存しますので、Stringは可変ではありません。
    下記の例を見て、hashCode方法の種類を書き換えていないで、直接32ビットの対象のJVMの中の住所に戻ります。Long類はhashCodeの方法を書き換えて、計算したhashCodeの数値を返します。
    public class ComHashcode{
        public static void main(String[] args) throws Exception {
            ComHashcode a = new ComHashcode();
            ComHashcode b = new ComHashcode();
            System.out.println(a.hashCode());    //870919696
            System.out.println(b.hashCode());    //298792720
    
            Long num1 = new Long(8);
            Long num2 = new Long(8);
            System.out.println(num1.hashCode());    //8
            System.out.println(num2.hashCode());    //8
        }
    }
    (1)バインディングequals方法が書き換えられると、通常はhashCode方法の従来の協定を維持するために、hashCode方法を書き換える必要があり、この協定は、同じオブジェクトが同じハッシュコードを持つ必要があると宣言する。
    (2)バインディングの原因hashtableは、ハッシュ・テーブルを実現し、ハッシュ・テーブルにオブジェクトを格納および検索することに成功するために、キーとして使用するオブジェクトは、hashCode方法およびequals方法を実装しなければならない。同じ(1)、equals等しい対象を保証しなければならない。hashCodeも同じである。なぜなら、ハッシュ表はhashCodeを通して対象を検索するからです。
    (3)デフォルト==デフォルトの比較対象はJVMのアドレスです。
    hashCodeデフォルトでは、JVMのオブジェクトの格納アドレスを返します。
    equal比較対象は、デフォルトも比較対象のJVMのアドレスです。同じ=