以下のコードを実行したらどうなるか。
(1)
Set set = new HashSet(); set.add(new Object()); set.add(new Object()); System.out.println(set.size());
(2)
class A { public boolean equals(Object obj) {throw new RuntimeException();} } Set set = new HashSet(); set.add(new A()); set.add(new A()); System.out.println(set.size());
(3)
class A { public int hashCode() {return 1;} } Set set = new HashSet(); set.add(new A()); set.add(new A()); System.out.println(set.size());
(4)
class A { public boolean equals(Object obj) {return true;} public int hashCode() {return 1;} } class B { public boolean equals(Object obj) {return true;} public int hashCode() {return 1;} } Set set = new HashSet(); set.add(new A()); set.add(new A()); set.add(new B()); System.out.println(set.size());
答え
- (1)2
- (2)2
- (3)2
- (4)1
わかる人には問題にすらならないんだよね。要するに「hashCodeが一致してequalsがtrueを返すものは同じものとして扱われる」ってだけです。hashCodeが一致しなきゃそもそもequalsなんて評価もされない。よくわからない人はJDKのコード読めばわかると思います。ついでにHashSetの中身はHashMapだってことも判るかも知れません。
hashCodeはハッシュテーブルで使われますが、これが何ものかを簡単に言うと、対象を絞り込むために使うようなものです。無理矢理現実に当てはめると、郵便番号や市外局番とかをイメージすると良いかもしれません。同じ郵便番号に複数の家があるように、同じhashCodeを持つ複数のオブジェクトが存在しえます。
hashCodeを使用する場合、まずhashCodeで絞り込んでからequalsで比較する事になります。これはhashCodeが十分に分散していたり、大量のオブジェクトが対象だったり、equalsの処理が重かったりする時に有効な手段になります。
当たり前のことを説明してみてボロが出ないか確認してみる。たぶん大丈夫だよね…。