3秒でわかる
キーから値をほぼ一定の時間で引ける Java の連想配列。件数が増えても検索の速さを落とさずに対応表を扱うために使います。
もう少し詳しく
どういうものか
HashMap は Java の Map インタフェースを実装したクラスで、キーと値の組を保持します。キーをハッシュ値に変換し、そこから配列上の位置を決めて格納するため、要素数が増えても検索や追加にかかる時間はほぼ一定です。並び順は保証されず、取り出す順番は入れた順とは限りません。
キーは重複できず、同じキーで put すると値が上書きされます。null もキーとして 1 つだけ入れられます。
なぜ必要か
社員番号から社員情報を引く処理を、リストの先頭から順に探して実装すると、1 万件のリストでは平均 5 千回の比較が必要です。HashMap ならハッシュ値の計算 1 回でほぼ目的の場所に届きます。件数が増えるほど差が開くため、対応表を扱う場面では既定の選択肢になります。
具体例
Map<String, Integer> stock = new HashMap<>();
stock.put("apple", 3);
stock.put("banana", 5);
stock.put("apple", 7); // 上書きされる
System.out.println(stock.get("apple")); // 7
System.out.println(stock.get("melon")); // null
System.out.println(stock.getOrDefault("melon", 0)); // 0
stock.<a href="/glossary/merge" class="text-primary font-medium underline underline-offset-2 hover:text-primary-dark">merge</a>("banana", 1, Integer::sum); // 6 に増やす
for (Map.Entry<String, Integer> e : stock.entrySet()) {
System.out.println(e.getKey() + " は " + e.getValue());
}似た用語との違い
| クラス | 順序 | スレッド安全 | 用途 |
|---|---|---|---|
| HashMap | 保証なし | なし | 既定の選択肢 |
| LinkedHashMap | 挿入順を保つ | なし | 順番も見せたいとき |
| TreeMap | キーの昇順 | なし | 範囲検索や整列が要るとき |
| ConcurrentHashMap | 保証なし | あり | 複数スレッドから触るとき |
つまずきやすいところ
自作クラスをキーにするとき、equals だけを上書きして hashCode を上書きしないと、同じ内容のオブジェクトで get しても null が返ります。格納位置がハッシュ値で決まるため、両方をセットで実装する必要があります。
get の戻り値を int 型の変数へ直接代入するのも危険です。キーが無いと null が返り、自動変換の過程で NullPointerException になります。getOrDefault を使うか、null を確かめてください。
拡張の途中で並び順が変わるため、表示順が意味を持つ場面では LinkedHashMap を選びます。