2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめてのアドベントカレンダーAdvent Calendar 2024

Day 3

equalsメソッドについての理解を深める Java

Last updated at Posted at 2025-01-01

はじめに

インフラの分野でも、Iac化が進んで行くと考えています。そこで、ノウハウが体系だっているものが学び易いと考えて、Javaを学びはじめました。

今回は、equalsメソッドをオーバーライドして、Sampleクラスの2つのオブジェクトを比較する方法です。

間違い探し

public class Sample {
    private int num;
    
    public Sample(int num) {
        this.num = num;
    }
    
    public boolean equals(Sample obj) {
        if (obj == null) {
            return false;
        }
        return this.num == obj.num;
    }
}

public class main {
    public static void Main(String[] args) {
        Object a = new Sample(10);
        Object b = new Sample(10);
        System.out.println(a.equals(b));
    }
}

1. equalsメソッドのオーバーライドに関する問題

まず、Sampleクラス内でのequalsメソッドはObjectクラスのequalsメソッドをオーバーライドするべきですが、シグネチャが少し間違っています。

  • Objectクラスのequalsメソッドは、Object型の引数を受け取ります。したがって、Sampleクラスのequalsメソッドは、Object型の引数を取るべきです。
  • さらに、Object型の引数に対応するために、型キャストを行う必要があります。

☝️修正後のコードでは、equals(Object obj)に変更します。

2. equalsメソッド内での型キャスト

equalsメソッドをオーバーライドする場合、引数として渡されたObject型をSample型にキャストする必要があります。キャストが失敗した場合のエラーを防ぐために、instanceofを使って型チェックを行うことが一般的です。

修正後のコード

public class Sample {
    private int num;
    
    // コンストラクタ
    public Sample(int num) {
        this.num = num;
    }
    
    // equalsメソッドのオーバーライド
    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;  // 同一オブジェクトであればtrueを返す
        if (obj == null || getClass() != obj.getClass()) return false; // nullまたは異なるクラスならfalse
        Sample sampleObj = (Sample) obj; // 型キャスト
        return this.num == sampleObj.num; // numフィールドを比較
    }
    
    // hashCodeもオーバーライドすべき
    @Override
    public int hashCode() {
        return Integer.hashCode(num); // numに基づいたhashCodeを返す
    }
}

public class Main {
    public static void main(String[] args) {
        Object a = new Sample(10);
        Object b = new Sample(10);
        System.out.println(a.equals(b)); // trueを出力するはず
    }
}
  1. equals(Object obj)メソッドのオーバーライド

    • equalsメソッドをObject型の引数を取るように変更しました。これにより、Objectクラスのequalsメソッドを正しくオーバーライドすることができます。
    • this == objを最初にチェックすることで、同一オブジェクトであれば即座にtrueを返します。
    • obj == null || getClass() != obj.getClass()で、objnullか、異なるクラスである場合はfalseを返します。これにより、型の不一致を防ぎます。
    • Sample sampleObj = (Sample) obj;で、objSample型にキャストします。
    • 最後にthis.num == sampleObj.numで、numフィールドを比較して、オブジェクトが等しいかどうかを判断します。
  2. hashCodeのオーバーライド

    • equalsメソッドをオーバーライドした場合、hashCodeメソッドもオーバーライドすることが推奨されます。hashCodeequalsと一貫性を持つ必要があるため、numフィールドを元にしたhashCodeを生成します。

出力結果

true
2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?