018 オブジェクト指向の深化(オブジェクトの比較とハッシュコーディング) 024 解答例

import java.util.Objects;

// カスタムオブジェクトを表すクラス
class CustomObject {
    private int intValue;
    private String stringValue;

    // コンストラクタで初期化
    public CustomObject(int intValue, String stringValue) {
        this.intValue = intValue;
        this.stringValue = stringValue;
    }

    // ハッシュコードの計算
    @Override
    public int hashCode() {
        // 異なる素数を使用してハッシュコードを計算
        int result = 17;  // 初期値に17を選ぶ(素数であることが好ましい)
        result = 31 * result + intValue;  // intValueが影響する部分のハッシュコードを加算
        result = 31 * result + Objects.hashCode(stringValue);  // stringValueが影響する部分のハッシュコードを加算
        return result;
    }

    // オブジェクトの等価性の比較
    @Override
    public boolean equals(Object obj) {
        // 同一のオブジェクトであるかどうかを最初に確認
        if (this == obj) return true;
        // nullや異なるクラスのオブジェクトは等価でないと見なす
        if (obj == null || getClass() != obj.getClass()) return false;

        // objをこのクラスの型にキャスト
        CustomObject other = (CustomObject) obj;

        // 各フィールドの等価性を比較
        return intValue == other.intValue &&
               Objects.equals(stringValue, other.stringValue);
    }

    // メインメソッドでのテスト
    public static void main(String[] args) {
        // オブジェクトの作成
        CustomObject obj1 = new CustomObject(42, "Hello");
        CustomObject obj2 = new CustomObject(42, "Hello");

        // ハッシュコードの一貫性を確認
        System.out.println("Hashcode of obj1: " + obj1.hashCode());
        System.out.println("Hashcode of obj2: " + obj2.hashCode());

        // equalsメソッドを使用してオブジェクトの等価性を確認
        System.out.println("obj1 equals obj2: " + obj1.equals(obj2));
    }
}

この例では、hashCodeメソッド内で異なる型のオブジェクトに対して異なる素数を使用してハッシュコードを計算しています。また、equalsメソッドもオーバーライドしています。これにより、hashCodeequalsが一貫して動作し、HashMapHashSetなどのコレクションで正しく機能します。ただし、実際のプロダクションコードではもっと注意深い実装が必要です。

「018 オブジェクト指向の深化」問題集リスト