hashcodeを書き直した理由となぜ31の個人で理解したのか

4320 ワード

まず自分の大部分の理解の出所を宣言します:どのようにhashCode()とequals()の方法を書き換えます次に自分の理解:1、まずjavaの中でset、HashMapはリストなどの下層の記憶を含むようで、記憶領域はnの部分に分けて、具体的にどの部分がhashcodeによって決定されたのか、つまりクエリーの時彼はhashcodeのすべての小さいクエリーの範囲を通じて、だから、すべてのhashcodeが同じであれば、あなたのhashcodeは定数を返します.その結果、格納された後、1つの領域に格納され、クエリーの時にチェーンクエリーになり、完全に効率的ではありません.2、hashcodeがランダム数を返しているか、hashcodeを書き直さないと、2つのオブジェクトが同じであっても問題が発生します.例(上のブログから適用):まず2つの新しいCoderオブジェクトを作成します.
Coder c1 = new Coder("bruce", 10);  
02.        Coder c2 = new Coder("bruce", 10);  

hashCode()メソッドを書き換えずにCoderのequals()メソッドを書き換えたと仮定します.
@Override  
02.    public boolean equals(Object other) {  
03.        System.out.println("equals method invoked!");  
04.          
05.        if(other == this)  
06.            return true;  
07.        if(!(other instanceof Coder))  
08.            return false;  
09.          
10.        Coder o = (Coder)other;  
11.        return o.name.equals(name) && o.age == age;  
12.    }  

次にHashSetを作成し、c 1オブジェクトをsetに入れます.
Set set = new HashSet();  
 set.add(c1); 

最後:
System.out.println(set.contains(c2));  

contains(c 2)法はtrueを返すことを期待するが,実際にはfalseを返す.
c 1とc 2のnameとageは同じですが、なぜ私はc 1をHashSetに入れた後、contains(c 2)を呼び出してfalseに戻ったのでしょうか.これがhashCode()です.hashCode()を書き換える方法がないので、HashSetはc 2を探すとき、異なるbucketの中で探します.例えばc 1は05というbucketの中に入っていますが、c 2を探すときに06というbucketの中で探しています.もちろん見つかりません.そのため、hashCode()を書き換える目的は、A.equals(B)がtrueを返す場合、A,BのhashCode()は同じ値を返す.
次にhashcodeを書き直すときに31という数で書くのが一般的です.
@Override  
02.    public int hashCode() {  
03.        int result = 17;  
04.        result = result * 31 + name.hashCode();  
05.        result = result * 31 + age;  
06.          
07.        return result;  
08.    }  

まずhashcodeを生成することをできるだけ一意に保つために、必ず1つの素数を係数(ここの31)として使用しますが、なぜ他の素数ではなく31なのか、31はi*31==(i<<5)-1で表すことができ、現在多くの仮想マシンでは関連最適化が行われていますが、31を使用する理由はhashアドレスをよりよく割り当てるためかもしれません.そして31は5 bitしか占めていません!したがって、効率的には2の5回のマイナス1であり、コンピュータにとって2の乗算除算操作は変位操作を行うだけであり、例えば*32は左シフト5ビットである.つまり、31はコンピュータの観点から言えば、演算が速く、メモリの切断が少なく、仮想マシンが最適化されているのが慣例です.したがって、31を係数としてhashcode以上の理解は、hashcodeに31係数が用いられている問題に関する理解に由来する.