【初心者必見】Javaでオリジナルなequals()メソッドの実装
オリジナルなequals()メソッドの実装を試してみましょう。
自転車クラスを考えます。この自転車クラスは防犯登録番号(registryNumber)が同じなら、同一であると判断するとします。先ほどのStringクラスのequals)メソッドを参考にして作成してみました。他の乗り物クラスでもequals()メソッドを持つことを想定し、汎用性を考えて仮引数を(Vehicle aVehicle)としました。(ちなみにequals()メソッドもIDEの機能を使えば簡単に挿入できるうえスペルミスを減らすことになります)
package chap10;
public class Bicycle extends Vehicle {
int registryNumber;
public Bicycle(int registryNumber) {
this.registryNumber = registryNumber;
}
@Override
public int hashCode() {
int hash = 5;
hash = 47 * hash + this.registryNumber;
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Bicycle other = (Bicycle) obj;
if (this.registryNumber != other.registryNumber) {
return false;
}
return true;
}
}
package chap10;
public class Example07 {
public static void main(String[] args) {
Bicycle bi1 = new Bicycle(110);
Bicycle bi2 = new Bicycle(110);
Bicycle bi3 = new Bicycle(119);
System.out.println(bi1.equals(bi2));
System.out.println(bi2.equals(bi3));
}
}
<実行結果>
true false |
<イメージ図>

ここで一見無関係に見えるhashCodeをオーバーライドしていることを不思議に思う人もいるかもしれません。
実は、equals()メソッドをオーバーライドしたときにはhashCode()メソッドもオーバーライドしないと、コレクションフレームワークのHashMap/HashSetなどのハッシュ表の要素としたときに深刻なバグを生む可能性があるのです。
ちなみにこのハッシュ値はごちゃまぜにするという意味でハッシュドビーフ(hashed beef)などと同じ語源でしたね。ここでは単純に防犯登録番号を返す仕様としています。数多くのインスタンスから目的のインスタンスをequals()メソッドで探すときには2段階の探索が行われるのです。つまり、最初はhashCodeの一致を見ます。しかし、hashCodeが偶然同じで別のインスタンスということはありえます。そこで絞り込んだ対象に対してequals()メソッドで等しいかどうかを見るのです。
なお、この例
equals(Vehicle aVehicle)
のようにメソッドの仮引数をスーパークラス型にすることで、サブクラス型の実引数を受け取れるようにしておくことをポリモーフィズムを使ったメソッドの引数設計と呼ぶことがあります。
大切な考え方ですので押さえてください。
たとえ話をしますと、「お母さんアレ取って」と言って理解しあえる夫婦のようなものです。アレの中身は状況により変わってもいいわけですね。この夫婦会話例のように私達は日常生活で抽象化の恩恵を受けていますが、ポリモーフィズムの目的は抽象化だとお考えください。ちなみに、このあと学ぶインタフェースを使うと更に抽象化の恩恵が受けられます。
セイ・コンサルティング・グループの新人エンジニア研修のメニューへのリンク
投稿者プロフィール

- 代表取締役
-
セイ・コンサルティング・グループ株式会社代表取締役。
岐阜県出身。
2000年創業、2004年会社設立。
IT企業向け人材育成研修歴業界歴20年以上。
すべての無駄を省いた費用対効果の高い「筋肉質」な研修を提供します!
この記事に間違い等ありましたらぜひお知らせください。