今回やること
HashMapは、キーと値を組にして保存するコレクションです。商品コードをキー、在庫数を値にした在庫表を一つ作ります。
前提: Java入門 #16 - ListとLinkedListまでのコレクションと繰り返しを理解していること。
| 操作 | この例での意味 |
|---|---|
put(key, value) | 商品コードと在庫数を登録・更新 |
get(key) | コードから在庫数を取得 |
containsKey(key) | 商品コードが登録済みか確認 |
remove(key) | 商品コードと値を削除 |
size() | 登録されたキーの件数 |
キーは重複できませんが、値は重複できます。別の商品コードが同じ在庫数を持っても問題ありません。
実務では変数の型をインターフェースのMapにする書き方もよく使います。
Map<String, Integer> stock = new HashMap<>();
この場合はjava.util.Mapとjava.util.HashMapの両方をimportします。完成例では基本操作の出どころを追いやすくするため、変数型をHashMapにしています。
1. putで登録する
HashMap<String, Integer> stock = new HashMap<>();
stock.put("A101", 5);
stock.put("B205", 3);
stock.put("C310", 5);
<String, Integer>は、キーが文字列、値が整数という意味です。同じキーへもう一度putすると、新しいペアが増えるのではなく値が更新されます。
stock.put("A101", 8);
この後、キーは3件のまま、A101の値だけが8になります。
2. getとcontainsKeyで調べる
if (stock.containsKey("A101")) {
System.out.println(stock.get("A101"));
}
存在しないキーをgetするとnullです。値の型がIntegerなのは、nullも扱える参照型だからです。存在確認が必要な処理では、先にcontainsKeyを使うと意図が明確です。
3. removeで削除する
stock.remove("B205");
キーB205と対応する値が一緒に削除されます。indexではなく、キーを指定して操作します。
完成コードを動かす
HashMapDemo.javaとして保存します。
import java.util.HashMap;
import java.util.Map;
public class HashMapDemo {
public static void main(String[] args) {
HashMap<String, Integer> stock = new HashMap<>();
stock.put("A101", 5);
stock.put("B205", 3);
stock.put("C310", 5);
stock.put("A101", 8);
if (stock.containsKey("A101")) {
System.out.println("A101の在庫: " + stock.get("A101"));
}
stock.remove("B205");
System.out.println("商品数: " + stock.size());
for (Map.Entry<String, Integer> entry : stock.entrySet()) {
System.out.println(entry.getKey() + " -> " + entry.getValue());
}
}
}
javac HashMapDemo.java
java HashMapDemo
entrySet()を使うと、キーと値を一度に取り出して繰り返せます。HashMapは表示順を保証しないため、最後の2行の順番は環境によって変わっても正常です。
操作後の状態
| 操作 | A101 | B205 | C310 | size |
|---|---|---|---|---|
| 最初の3件をput | 5 | 3 | 5 | 3 |
| A101を更新 | 8 | 3 | 5 | 3 |
| B205をremove | 8 | — | 5 | 2 |
値を上書きしてもキー数は増えません。商品コードのように重複してはいけない識別子をキーへ選びます。
商品名のように後から変わり得る値より、商品コードのように安定した値をキーへ選ぶと、更新や検索の規則が分かりやすくなります。
成功確認
A101の在庫が8になるB205を削除後の商品数が2になる- 残った
A101とC310が表示される - 最後の表示順には依存しない
よくあるつまずき
存在しないキーを数値へ代入する
getはnullを返すことがあります。必ず登録されている前提にせず、containsKeyまたは既定値を返すgetOrDefaultを用途に合わせて使います。
putで同じキーを追加して件数が増えると思う
同じキーのputは更新です。更新前の値が必要なら、putの戻り値を確認します。
entrySetの順番を期待する
HashMapの列挙順は保証されません。表示順が仕様なら、並び順を別に設計します。
練習
英単語と日本語訳を入れるHashMap<String, String>を作ってください。3件登録し、1件更新し、1件削除した後、残ったキーと値を表示します。
次のステップ
Java入門 #18 - HashSetで、値を重複なしで管理する集合を学びます。