【Java】hashCodeメソッドについて

オブジェクトクラスの同値を定義するequalsメソッドを実装した場合、
hashCodeメソッドも合わせて実装しなくてはならない。

equalsメソッドについての記事はこちら

hashCodeメソッド
オブジェクトのハッシュ値を返すメソッド。
ハッシュ値
オブジェクトの値を一定のルールにしたがって数値化したもの。
ハッシュ値に期待すべき事
インスタンスが異なればハッシュ値も異なる。
同じ値を持つオブジェクトは同じハッシュ値となる。

 

なぜ、hashCodeメソッドが必要なのか

java.utilパッケージのHashMapやHashSetなどハッシュ系のコレクションクラスでは、
equalsメソッドによる等価判定は比較的大きな計算コストがかかるため最初にハッシュ値でオブジェクトを比較し、ハッシュ値が等しい場合に限り、equalsメソッドで判定を行う。

ハッシュ値が同じでもまれに同じ値を持っていない場合もあるのでequalsメソッドで厳密にチェックしている。

ObjectクラスのhashCodeメソッドはオブジェクトが異なれば、異なるハッシュ値を返すというデフォルトの仕様になっている。

よって、仕様通りの動きを実現するためにはhashCodeメソッドをオーバーライドしてハッシュ値を正しく返さなければならない。

HashSetクラスを例にする

Setにオブジェクトを要素として追加する場合、
二つのオブジェクトが同値であってもハッシュ値が異なるために異なるオブジェクトと認識され、
同じ値を持ったオブジェクトが重複してHashSetに追加されてしまう。

HashSet(Setインターフェース)は重複する要素を保持しない特徴を持っているため、
本来の仕様の動きに反している。(本来期待すべき結果は1)

 

実行結果(コンソールへ出力)
2

 
equalsメソッドと同じようにhashCodeメソッドをオブジェクトクラス内でオーバーライドして、
同値である場合、同じハッシュ値を持つように定義する。

Eclipseの自動生成機能でequalsメソッドとhashCodeメソッドを同時に定義する

 
再びHashSetに存在する要素数を取得しコンソールに出力する。
 

実行結果(コンソールへ出力)
1

 

hashCodeが返す値(ハッシュ値)が等しくなり値も同じなので、
HashSet本来の仕様通り、要素が正しく上書きされて追加されるようになる。
(重複しない)

 
Objects.hashメソッドを使ってhashCodeを生成する事もできる。

(※Java 7からの仕様)


HashMap、HashSetなどが仕様通りに正しく動かせるよう、
オブジェクトクラスのequalsメソッドを定義した際にはhashCodeメソッドも忘れずに定義するようにしておきたい。

Follow me!

【Java】hashCodeメソッドについて” に対して1件のコメントがあります。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください