はじめに
Javaの開発をしていると、HashMap や HashSet を使ったときに「要素が見つからない」「同じものが重複して入ってしまう」といったトラブルに遭遇することがあります。equalsとhashCodeの実装が正しくない可能性があるためこの記事を参考にしてみてください。
他にも、体系的にJavaを学びたい方には以下の教材がおすすめです:
👉スッキリわかるJava入門
👉スッキリわかるJava入門 実践編
equalsとは
equals メソッドは「2つのオブジェクトが同じ内容かどうか」を判定します。equalsメソッドは作成したclass(Object)にはデフォルトで存在しますが、デフォルトのequalsメソッドは同じインスタンスかどうかのみが比較(instanceof)されているため、特定の項目でのequals判定を実施したい場合は、equalsメソッドをオーバーライドしてclassに持たせる必要があります。
equalsのルール
- x.equals(x) は常にtrueである
- x.equals(y) がtrueなら、y.equals(x) もtrueである
- x.equals(y) と y.equals(z) がtrueなら、x.equals(z) もtrueである
- 状態が変わらなければ、何度比較しても結果は同じである
- nullとの比較: どんなオブジェクトも x.equals(null) はfalseである
hashCodeとは
hashCode メソッドは、オブジェクトをハッシュ値(数値)に変換するためのものです。HashMap や HashSet はこの値を使って要素を探したり、格納場所を決めたりします。
hashCodeのルール
- equalsで等しいオブジェクトは、必ず同じhashCodeを返す
- equalsで異なるオブジェクトでも、同じhashCodeを返すことはある(衝突は許容)
- オブジェクトの内容が変わらない限り、同じhashCodeを返す
- equalsをオーバーライドしたら必ずhashCodeもオーバーライドする必要がある
実装例
package com.dao;
import java.util.Objects;
public class User {
private String id;
private String name;
public User(String id, String name) {
this.id = id;
this.name = name;
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (!(o instanceof User))
return false;
User other = (User) o;
return Objects.equals(id, other.id) && Objects.equals(name, other.name);
}
@Override
public int hashCode() {
return Objects.hash(id, name);
}
}
実装のポイント
- equalsで比較したフィールドは、必ずhashCodeにも使う
- オブジェクトでイコールとしたい「id」「name」で比較した結果を返却するequalsメソッドをオーバーライドする
- hashCodeメソッドで、「id」「name」をハッシュ値として返却する
失敗例
- equalsだけ実装してhashCodeを忘れる
- equalsとhashCodeで異なるフィールドを使う
Lombokで自動生成する方法
Javaのライブラリである Lombok を使うと、アノテーションを付けるだけで equals と hashCode を自動生成できます。
例
import lombok.EqualsAndHashCode;
@EqualsAndHashCode
public class User {
private String id;
private String name;
}
まとめ
equals と hashCode は、Javaの開発において「ただの比較メソッド」ではなく、プログラム全体の信頼性を左右する基盤的な仕組みです。
この記事の内容を押さえておけば、equalsとhashCodeに関するトラブルは大幅に減り、コードの可読性や保守性もぐっと向上します。
最後に
Javaの環境構築は、この記事を参照してみてください。
【開発環境構築】VS CodeでJavaを使用するための環境構築を実施する – SEもりのLog (selifemorizo.com)
以上、ログになります。
これからも継続していきましょう!!
コメント