【Java】equalsとhashCodeの使い方(オーバーライド)

Java

はじめに

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)

以上、ログになります。
これからも継続していきましょう!!

Javaサーバーサイド関連
シェアする
おすすめIT本
良いコード/悪いコードで学ぶ設計入門

「ITエンジニア本大賞2023」技術書部門で大賞を受賞した本です。
・コードの可読性
・普段意識したほうが良いこと
・リファクタリング考え方
等、普段のコードを設計する際に意識することが書かれています。
コードのあるべき姿に迷ったら一度読んでみると良い本です。

仕組みと使い方がわかる Docker&Kubernetesのきほんのきほん

Dockerって何?となったときに私が最初に読んだ本です。
Dockerがどんな仕組みで動いているのか、コマンドでは何を命令しているのかを理解できるように、イラストを多用して説明しています。

1冊ですべて身につくJavaScript入門講座

「ITエンジニア本大賞2024」技術書部門で大賞を受賞した本です。
私が次に読もうと思っている本なのでおすすめとして挙げておきたいと思います。

コメント

タイトルとURLをコピーしました