hashCodeは、HashMapやHashSetでオブジェクトを探しやすくするための整数値です。
Javaでは、オブジェクト同士が同じかどうかをequalsで判断します。ただし、HashMapやHashSetのようなクラスでは、効率よく探すためにhashCodeも使います。

まずは『equalsで同じなら、hashCodeも同じにする』というルールだけ押さえれば大丈夫です。
この記事では、hashCodeの意味、既存記事との違い、コードの読み方、初心者がつまずきやすい点を順番に整理します。
まず結論:hashCodeは探すための番号
hashCodeは、オブジェクトを分類するための番号のようなものです。完全な住所ではありませんが、探す範囲を絞るために使われます。だからこそ、equalsと矛盾しないことが重要です。
次の図では、hashCodeを『探す棚番号』として見てください。

棚番号だけで同一性が決まるのではなく、最後にequalsで確認する点が重要です。
equalsとの関係
| 比較 | equals | hashCode |
|---|---|---|
| 役割 | 同じ内容か判断する | 探すための番号を返す |
| 戻り値 | boolean | int |
| 使われる場面 | 比較全般 | HashMap/HashSetなど |
| 守るルール | 同じならtrue | equalsがtrueなら同じ値 |
equalsの基本はJavaのequalsメソッドで扱っています。この記事は、その次に読む補助記事です。
まずはこのコードを読めればOK
まずは、同じIDなら同じユーザーとして扱うクラスを見てみます。
import java.util.Objects;
class User {
private final String id;
User(String id) {
this.id = id;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof User other)) return false;
return Objects.equals(this.id, other.id);
}
@Override
public int hashCode() {
return Objects.hash(id);
}
}
この例では、idが同じなら同じユーザーとして扱います。そのため、equalsとhashCodeの両方でidを使っています。
HashSetで問題になる流れ
次の図では、HashSetの中でhashCodeとequalsが使われる順番を確認してください。

この順番を知っておくと、equalsだけを実装したときの危険性が分かりやすくなります。
HashSetは、まずhashCodeで候補を絞り、その後equalsで本当に同じかを確認するイメージです。hashCodeだけで同一性が完全に決まるわけではありません。
初心者がつまずきやすいポイント
| つまずき | まずこう読む |
|---|---|
| equalsだけオーバーライドする | HashSetやHashMapで意図しない動きになる |
| hashCodeが違ってもequalsで同じならよいと思う | equalsがtrueならhashCodeも同じ必要がある |
| hashCodeが同じなら必ず同じと思う | 同じhashCodeでも別物の場合がある |
| 変わる値をhashCodeに使う | HashSet投入後に探せなくなることがある |
最後の図では、hashCodeで混同しやすい3点を確認してください。

この3点を押さえれば、hashCodeの契約を実務コードで読み違えにくくなります。
hashCodeを意識する場面
実務ではIDEがequalsとhashCodeを生成してくれることも多いですが、何を同一性の基準にするかは開発者が決める必要があります。
次の図では、keyに使う値が途中で変わるとなぜ危険かを見てください。

hashCodeに使う値が変わると、探しに行く棚が変わり、入れたはずの値を見つけにくくなります。
実務コードで読むときのコツ
実務コードでhashCodeが出てきたら、最初に見るべきなのは『何を扱うために使っているのか』です。クラス名やメソッド名だけを暗記するより、データの目的を日本語に直す方が理解しやすくなります。
次に、変数の型、呼び出しているメソッド、戻り値の3つを順番に確認します。型を見ると入れ物の性質が分かり、メソッドを見ると何をしたいのかが分かり、戻り値を見ると次の処理へどうつながるかが分かります。
この記事の範囲では、hashCodeを完全に使いこなすことよりも、初見のコードで立ち止まらないことを優先しています。細かい仕様は公式APIで確認しながら、まずは代表的な使い方を読める状態を作りましょう。
チーム開発では、同じ機能を別の書き方で実現できる場合もあります。そのため『この書き方だけが正解』と覚えるのではなく、なぜその場面でそのクラスや構文が選ばれているのかを考えるのが大切です。
もう1つ大事なのは、サンプルコードと実務コードでは情報量が違うという点です。実務コードでは、変数名、メソッド名、例外処理、戻り値の受け渡しが同時に出てきます。読み始めで混乱したら、まずこのページで扱った最小コードまで戻し、1行ずつ役割を書き出すと整理できます。
特にhashCodeのような基礎概念は、単独で覚えるより、既存記事の文法やクラスライブラリとつなげて読む方が定着します。『どの前提知識が使われているか』を確認する癖をつけると、初めて見るAPIや構文にも対応しやすくなります。
判断に迷ったときの基準
hashCodeを使うべきか迷ったときは、先に目的を言葉にしてみます。目的が言葉で説明できないままコードを書き始めると、似たクラスや似た構文との違いが見えなくなります。
| 確認すること | 見るポイント |
|---|---|
| 扱いたいデータ | 値、一覧、例外、日付など何を扱うのか |
| 必要な操作 | 追加、比較、変換、確認、表示など何をしたいのか |
| 既存記事との関係 | 基礎文法、クラス、コレクション、例外処理のどれにつながるか |
| 注意点 | 順番、null、例外、戻り値、不変性など見落としやすい点 |
この4点を先に確認すると、単なる暗記ではなく、コードを読むための判断軸ができます。初心者向けの記事でも、この判断軸まで持てると、次の応用記事へ進みやすくなります。
練習問題
理解を確認するために、次の観点でサンプルコードを自分で説明してみてください。実行できる環境がある場合は、少し値を変えて結果がどう変わるかも試すと定着しやすくなります。
練習では、正確な用語を最初から完璧に使う必要はありません。まずは『何を入れて、何を取り出し、どの条件で動きが変わるのか』を自分の言葉で言えることを目標にしてください。
よくある疑問
最初から細かい仕様まで覚えるべき?
最初からすべてのメソッドや内部仕様を暗記する必要はありません。初心者の段階では、代表的な使い方、よくあるつまずき、既存記事とのつながりを押さえれば十分です。必要になったタイミングで公式APIを確認する習慣を作りましょう。
既存記事とは何が違う?
equals、HashMap、HashSetをつなぐ基礎概念記事。コレクションの重複判定と検索の背景を補う。
次に何を読めばよい?
次に読む記事は、本文末尾の内部リンクから選ぶのがおすすめです。基礎概念が不安なら親記事へ戻り、コードの応用を見たい場合は関連する文法やライブラリの記事へ進むと理解がつながります。
既存記事とあわせて読む順番
equals、hashCode、HashSet、HashMapはまとめて理解すると効果的です。特に自作クラスをコレクションに入れる前に、この関係を押さえておくと不具合を避けやすくなります。
公式情報と関連して読みたい記事
まとめ
hashCodeは、HashMapやHashSetが要素を探すときに使う整数値です。
hashCodeを理解すると、equalsだけでは見えにくかったコレクションの動きが読みやすくなります。
