Menu

Java HashMap: put、get、反復処理、よく使うパターン

キーと値の検索に Java の HashMap を使う方法: put、get、getOrDefault、containsKey、エントリの反復処理、そして最もよく使うパターン。

このページのコードはエディタで実行できます - 編集してすぐに結果を確認できます。

Map はキーと値のペアを格納する

HashMapjava.util 由来)は対応関係を格納します。各キーは 1 つのにマッピングされ、キーを使ってほぼ一定時間で値を検索できます。辞書を思い浮かべてください。単語がキーで、定義が値です。

2 つの型パラメータは <KeyType, ValueType> です。ここではキーが String、値が Integer です。ArrayList と同様に、通常は変数を Map インターフェース型として宣言し、HashMap を生成します。

put、get、上書き

身につけておくべき 2 点:

  • キーは一意です。既存のキーで put すると、その値が置き換えられ、古い値が返されます。
  • 存在しないキーで get すると、エラーではなく null が返されます。その nullint に自動アンボックスすると NullPointerException がスローされ、よくあるバグの原因になります。

getOrDefault は null の罠を避ける

毎回 null をチェックする代わりに、デフォルト値を求めましょう:

これは「存在するかもしれない」検索を扱う最もすっきりした方法であり、最も有名な HashMap のパターンへ直接つながります。

出現回数を数える

各要素が何回現れるかを数えるのは、HashMap の教科書的な用途です:

map.put(key, map.getOrDefault(key, 0) + 1) というパターンは「現在のカウント(またはゼロ)を取り、1 を足して、書き戻す」と読めます。よりすっきりした等価表現は counts.merge(word, 1, Integer::sum) です。

確認と削除

putIfAbsent(key, value) はキーが存在しないときだけ書き込みます。遅延初期化に便利です。

HashMap をループする

最もよく使うループは entrySet() をたどり、各キーと値をまとめて取得します:

キーだけ、または値だけが必要な場合:

ラムダを使って forEach を使うこともできます: ages.forEach((name, age) -> System.out.println(name + ": " + age));

HashMap は順序を保持しない

HashMap は反復処理の順序について何も保証しません。順序はハッシュ化の結果であり、実行ごとに変わることがあります。予測可能な順序が必要な場合:

  • LinkedHashMap は挿入順を保持します。
  • TreeMap はキーを自然順序(または指定した Comparator)でソートして保持します。

3 つとも Map インターフェースを実装しているので、切り替えはコンストラクタの 1 行を変えるだけです。

キーはハッシュ可能でなければならない

HashMap はキーをハッシュ化してエントリを見つけるため、キーの hashCode()equals() は整合している必要があります。StringInteger などの組み込み型はすでに正しく実装されています。独自のクラスをキーに使う場合は、equalshashCode の両方をオーバーライドしてください。そうしないと、意味的に「等しい」2 つのオブジェクトが別々のバケットに入り、検索が原因不明の失敗を起こします。

次へ: HashSet

HashMap は「このキーの下に格納されている値は何か?」に答えます。何かが存在するかどうかだけを気にする場合(関連データを持たない、一意な値の集合)に使うツールが HashSet で、これが次のテーマです。

よくある質問

Java で HashMap を作成するには?

2 つの型パラメータ(キーの型と値の型)を指定して宣言し、コンストラクタを呼び出します: Map<String, Integer> ages = new HashMap<>();。次に ages.put("Ada", 36); でエントリを追加し、ages.get("Ada"); で読み取ります。java.util.HashMapjava.util.Map をインポートしてください。

Java で HashMap をループ処理するには?

for-each ループで map.entrySet() を反復処理すると、各キーと値をまとめて取得できます: for (Map.Entry<String, Integer> e : map.entrySet()) { ... }。そして e.getKey()e.getValue() を読み取ります。キーだけが必要なら map.keySet()、値だけが必要なら map.values() をループすることもできます。HashMap は挿入順を保持しない点に注意してください。

get と getOrDefault の違いは?

get(key) はキーに対応する値を返しますが、キーが存在しない場合は null を返すため、結果をそのまま使うと NullPointerException につながる可能性があります。getOrDefault(key, fallback) は値があればそれを返し、なければ渡したデフォルト値を返すので、null チェックを省けます。特にカウント処理で便利です: counts.put(c, counts.getOrDefault(c, 0) + 1)

Coddy programming languages illustration

Coddyでコードを学ぼう

始める