【完全図解】JavaのHashMapの中身とは?内部構造と仕組みをやさしく解説!

Java

はじめに

Javaを学んでいると、必ず出てくる HashMap

でも、こう思いませんか?

  • 「使い方はわかるけど、内部で何してるの?」
  • putget の仕組みってどうなってるの?」
  • 「なぜ高速なの?」

この記事では、そんな疑問を図解&例付きでスッキリ解消!

Javaの HashMap の中身を、基礎からしっかり解説します。


HashMapは何のためにあるの?

  • 「キー」と「値」をペアで管理するデータ構造
  • たとえば「名前 → 年齢」や「商品名 → 在庫数」などを保存するのに使います
  • 最大の特徴は、高速な検索(平均 O(1))

HashMapの内部構造(図解)

HashMapの内部構造図

構成要素:

要素説明
table(配列)バケットの配列(Node[])
バケット同じインデックスにあるデータの入れ物
ノードキー、値、ハッシュ、nextを持つ
nextバケット内でノードをつなぐ
TreeBinノードが多いと赤黒木に変化

データ追加(put)の流れ

この1行で内部ではこんなことが起きています!

  1. ハッシュ値を計算"apple".hashCode()
  2. 補正処理で分散を改善(h ^ (h >>> 16)
  3. インデックスを計算hash & (table.length - 1)
  4. そのインデックスのバケットを見る
    • 空いていればそのままノードを入れる
    • 他のノードがあれば「衝突処理」へ
  5. 衝突があればequals()でキー比較し、上書き or 新規追加
  6. バケットが混みすぎたら:リスト → 赤黒木(TreeBin)に変換
  7. 容量オーバーなら:table を 2倍に拡張(再ハッシュ)

データ取得(get)の流れ

  1. ハッシュ値を計算して
  2. インデックスを求めて
  3. 該当バケットのノードを順に見て
  4. equals() でキーが一致すれば値を返す!

ポイント:検索も高速!O(1)で取得できることが多い


衝突とは?なぜ起きる?

「違うキーが同じインデックスに入る」=これが衝突(コリジョン)

たとえば:

→ その場合、next を使って「つなげる(チェーン)」方式になります


ノードが多すぎると…木に変身!?

  • バケット内のノード数が8以上(Java 8以降)になると
  • リンクリスト → 赤黒木(TreeBin) に変換!
  • 探索が O(n) → O(log n) に高速化!

これが HashMap の 「賢い設計」ポイントです。


配列が足りなくなったら?

  • HashMapは自動で容量を増やします!
  • 要素数が一定(初期容量 × 負荷率 0.75)を超えると
  • resize() という処理が走り、tableのサイズが 2倍 になります

nullキーやnull値は使える?

はい、使えます!

  • キーに null → OK(ただし1個だけ)
  • 値に null → OK(何個でも)

実際のNode構造は?

この構造が HashMap の「中身そのもの」!


よくある質問Q&A

Q. なぜハッシュ値に補正をかけるの?

→ 偏りを防ぐため。hashCode() だけだと分布が悪くなるケースがあるから!

Q. HashMap の速度が遅くなるときはある?

→ 衝突が多くてチェーンが長くなると、O(n)に近づくことがある。初期サイズを大きめにしておくと安心!

Q. Hashtable との違いは?

HashMap非同期(高速)Hashtable同期処理あり(遅いが安全)


初心者がまず知っておくべきことまとめ

  • HashMap は内部に「配列+ノード+チェーン」でできている
  • キーの hashCode() でバケットを決定
  • 衝突があればチェーンでつなぐ
  • ノードが多ければ木に変換
  • 再ハッシュや補正など、細かい工夫がいっぱい!

自分でも動かして学ぼう!

実際にコードを書いて、内部で何が起きているかイメージしながら学ぶのが一番!


本気で学びたい人へ

HashMapのような内部構造の理解はJava中級者への第一歩

コメント

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