Java HashMapの使い方完全ガイド|put・get・removeの基本操作
生徒
「Javaで、出席番号と名前のように、二つのデータをセットで管理したいときはどうすればいいですか?」
先生
「そういう時は、Javaのコレクションフレームワークにある『HashMap』というクラスを使うのが一番便利ですよ。」
生徒
「ハッシュマップ…ですか。配列やリストとは違うんですか?」
先生
「配列は番号で管理しますが、HashMapは『キー』と『値』というペアでデータを保存します。非常に高速に検索ができる特徴があるんです。基本操作のputやgetから一緒に学んでいきましょう!」
1. HashMapとは?キーと値のペアでデータを管理する仕組み
Javaのプログラミングにおいて、データを管理する方法は多岐にわたります。その中でも頻繁に利用されるのがHashMapです。HashMapは「Map」インターフェースを実装したクラスで、特定の「キー(Key)」に対して「値(Value)」を紐付けて保存するデータ構造を持っています。
例えば、電話帳をイメージしてください。名前を検索すると、その人の電話番号が出てきます。この場合、「名前」がキーであり、「電話番号」が値となります。配列やArrayListでは、要素を取り出す際に「○番目」という添え字(インデックス)を指定しますが、HashMapでは自分が設定した自由なキーを使って、一瞬で目的の値を取り出すことができます。
この仕組みを「連想配列」や「ハッシュテーブル」と呼ぶこともあります。大量のデータの中から特定の情報を素早く見つけ出す必要がある場面において、HashMapは非常に強力なパフォーマンスを発揮します。初心者の方は、まずは「二つの情報をセットにして、名前をつけて保存する箱」だと考えると分かりやすいでしょう。
2. HashMapの宣言とインスタンス生成の基本
HashMapを使うためには、まず宣言とインスタンスの生成を行う必要があります。HashMapはジェネリクス(型引数)を使用して、キーの型と値の型をそれぞれ指定します。一般的には、java.util.HashMapとjava.util.Mapをインポートして使用します。
記述する際の構文は、Map<キーの型, 値の型> 変数名 = new HashMap<>();となります。左辺にインターフェースであるMapを、右辺に具体的なクラスであるHashMapを書くのがJavaのプログラミングにおける推奨される作法です。これにより、将来的にプログラムの修正が容易になるというメリットがあります。型には、String(文字列)やInteger(整数)などの参照型を指定します。基本データ型のintなどはそのまま使えないため、ラッパークラスを使う点に注意しましょう。
import java.util.HashMap;
import java.util.Map;
public class MapInitExample {
public static void main(String[] args) {
// キーがString型、値がInteger型のHashMapを作成
Map<String, Integer> fruitPrices = new HashMap<>();
System.out.println("マップを生成しました。");
}
}
マップを生成しました。
3. putメソッドでデータを追加する方法
生成したマップにデータを登録するには、putメソッドを使用します。このメソッドには二つの引数を渡します。第一引数に「キー」、第二引数に「値」を指定します。もし既に存在するキーに対して再度putを行うと、以前の値は新しい値に上書きされます。これは、マップ内においてキーは唯一無二(ユニーク)でなければならないというルールがあるためです。
データの追加は非常に直感的です。例えば、ユーザーIDをキーにしてユーザー名を値として保存したり、商品名をキーにして在庫数を値として保存したりすることができます。注意点として、キーにnullを使うことも可能ですが、プログラムのバグを防ぐために通常はnullを避けるのが一般的です。以下のサンプルコードでは、果物の名前と価格を登録する様子を確認してみましょう。
import java.util.HashMap;
import java.util.Map;
public class MapPutExample {
public static void main(String[] args) {
Map<String, Integer> inventory = new HashMap<>();
// データの追加(put)
inventory.put("Apple", 150);
inventory.put("Banana", 100);
inventory.put("Orange", 120);
// 同じキーで追加すると上書きされる
inventory.put("Apple", 200);
System.out.println("現在の在庫情報: " + inventory);
}
}
現在の在庫情報: {Apple=200, Orange=120, Banana=100}
4. getメソッドでデータを取得する基本操作
保存したデータを取り出すには、getメソッドを使用します。引数に取得したいデータの「キー」を渡すと、それに対応する「値」が返ってきます。もし、指定したキーがマップの中に存在しない場合は、コンパイルエラーにはならずnullが返却されます。このため、getで取得した値を使用する際は、nullチェックを行うか、後述する存在確認のメソッドを併用するのが安全です。
HashMapの最大の強みは、このgetメソッドによる検索スピードにあります。リストのように先頭から順番に探すのではなく、ハッシュ値という仕組みを利用して目的の場所に直接アクセスするため、データが何万件あっても瞬時に値を取り出すことが可能です。これが、実務のシステム開発においてHashMapが多用される大きな理由の一つです。
import java.util.HashMap;
import java.util.Map;
public class MapGetExample {
public static void main(String[] args) {
Map<String, String> userMap = new HashMap<>();
userMap.put("user01", "田中太郎");
userMap.put("user02", "佐藤花子");
// キーを指定して値を取得
String userName = userMap.get("user01");
System.out.println("ID 01のユーザー名: " + userName);
// 存在しないキーを指定した場合
String unknown = userMap.get("user03");
System.out.println("ID 03の結果: " + unknown);
}
}
ID 01のユーザー名: 田中太郎
ID 03の結果: null
5. removeメソッドによるデータの削除手順
マップから特定のデータを削除したい場合には、removeメソッドを使います。削除したいエントリ(キーと値のペア)の「キー」を引数に指定することで、そのデータ一式を削除できます。削除に成功すると、そのキーに紐付いていた値が戻り値として返されます。もし指定したキーが存在しなかった場合は、何も削除されずnullが返ります。
また、全てのデータを一括で削除したい場合にはclearメソッドという便利な命令も用意されています。一時的に計算用として使ったマップを初期化したい時などに役立ちます。データの削除はメモリ管理や不要な情報の整理において重要ですので、適切に使いこなせるようになりましょう。不要になったデータを放置せず削除することで、プログラムの動作を健全に保つことができます。
import java.util.HashMap;
import java.util.Map;
public class MapRemoveExample {
public static void main(String[] args) {
Map<String, String> capitalMap = new HashMap<>();
capitalMap.put("Japan", "Tokyo");
capitalMap.put("USA", "Washington");
capitalMap.put("France", "Paris");
System.out.println("削除前: " + capitalMap);
// データを削除
String removedValue = capitalMap.remove("USA");
System.out.println("削除された値: " + removedValue);
System.out.println("削除後: " + capitalMap);
}
}
削除前: {USA=Washington, Japan=Tokyo, France=Paris}
削除された値: Washington
削除後: {Japan=Tokyo, France=Paris}
6. containsKeyでキーの存在をチェックする重要性
先ほど、存在しないキーに対してgetを使うとnullが返ると説明しましたが、事前にキーが存在するかどうかを調べたい場合があります。その時に使うのがcontainsKeyメソッドです。このメソッドは、引数に指定したキーがマップに含まれているかどうかを判定し、存在すればtrue、存在しなければfalseを返します。
条件分岐(if文)と組み合わせて使うことで、予期しないNullPointerException(ヌルポ)の発生を防ぐことができます。特に、外部から入力された値をキーとして使う場合や、設定ファイルの内容を読み込む場合などは、必ず事前にチェックを行う習慣をつけましょう。値の存在を調べるcontainsValueメソッドもありますが、キーのチェックに比べると処理速度が遅いため、基本的にはキーによるチェックが推奨されます。
7. sizeメソッドとisEmptyでマップの状態を把握する
プログラムの中で、現在マップにどれだけのデータが格納されているかを知りたい場面は多々あります。その際に役立つのがsizeメソッドです。このメソッドを呼び出すと、現在登録されているキーと値のペアの数を整数(int型)で返してくれます。ループ処理の回数を制御したり、データの入力漏れがないか確認したりするのに重宝します。
また、マップが空であるかどうかを判定するためのisEmptyメソッドも非常に便利です。size() == 0と書くのと同じ意味ですが、コードの読みやすさ(可読性)の観点からはisEmptyを使う方が「空かどうかをチェックしている」という意図が明確に伝わります。例えば、検索結果が一件も見つからなかった場合の処理を記述する際などに頻繁に登場するテクニックです。
8. HashMapの繰り返し処理!全データを取得する方法
最後に、マップに格納されている全てのデータを順番に取り出して処理する方法を紹介します。マップはリストと異なりインデックス番号がないため、通常のfor文では回せません。一般的には、拡張for文を使用して、キーの集合を取得するkeySetメソッドや、キーと値のペアを保持するオブジェクトを取得するentrySetメソッドを利用します。
特にentrySetを使う方法は、キーと値の両方を一度に効率よく扱えるため、実務で最も推奨されるループの方法です。各エントリを取り出し、getKey()メソッドとgetValue()メソッドを呼び出すことで、保存されている内容を全て表示したり計算に利用したりできます。最近のJavaではforEachメソッドとラムダ式を使ってさらに簡潔に記述することも可能になっており、用途に合わせて最適な書き方を選べるようになると上級者への第一歩となります。
import java.util.HashMap;
import java.util.Map;
public class MapLoopExample {
public static void main(String[] args) {
Map<String, Integer> scores = new HashMap<>();
scores.put("国語", 85);
scores.put("数学", 90);
scores.put("英語", 78);
// 全データをループで処理
for (Map.Entry<String, Integer> entry : scores.entrySet()) {
System.out.println("科目: " + entry.getKey() + "、点数: " + entry.getValue());
}
}
}
科目: 国語、点数: 85
科目: 数学、点数: 90
科目: 英語、点数: 78