Mapとは?
Mapとは、一意(ユニーク)のキーと値のペアで管理できるデータ構造になります。
キーは日本語で鍵という意味があり一意である必要があります。
値はキーに紐づくデータを入れておくことで、この鍵のものはこのデータという管理ができます。
Java以外の言語であれば、「辞書」や「連想配列」と呼ばれたりもします。
Mapの実装種類
Mapを使う際、一番使用頻度が高いのがHashMapです。
HashMapの宣言は以下の通りです。型は参照型になります。(intなどの基本型はコンパイルエラー)
// Map<キーの型, 値の型> 変数名 = new HashMap<>();
Map<String, String> data = new HashMap<>();
このHashMap以外にも様々な実装型があります。
HashMap
HashMapは、使用頻度が一番高いですが、
癖もあるので適当に使用しているとバグの原因にもなります。
注意すべき点は、HashMapに格納したデータは必ず格納した順番にはなりません。
もう一つは、HashMapに限りませんがキーが重複した場合は、上書きされる点に注意が必要です。
内部でキーのハッシュ値をもとにデータの格納場所が決まります。
つまり、キーをオブジェクトにする場合、同じハッシュ値をもつオブジェクトは
上書きされてしまいます。
Map<String, String> data = new HashMap<>();
// データの格納
data.put("Monkey", "サル");
data.put("Dog", "犬");
data.put("Cat", "猫");
// データの取り出し
for (var val : data.entrySet()) {
System.out.println(val);
}
// Monkey=サル
// Cat=猫
// Dog=犬
上記のように、キーのデータによっては、順序が保証されないため、注意が必要です。
拡張for文のように順番に取り出さず、getメソッドを使用して取り出す分には問題ありません。
System.out.println(data.get("Dog"));
// 犬
TreeMap
TreeMapは並び替えが可能なMapです。
宣言は以下の通りです。
Map<String, String> data = new TreeMap<>();
キーの型がStringであれば辞書順で並び替えされ、
Integer型などの数値型であれば大小順になります。
それでは、実際に見てみましょう。
Map<String, String> data = new TreeMap<>();
// データの格納
data.put("Monkey", "サル");
data.put("Dog", "犬");
data.put("Cat", "猫");
// データの取り出し
for (var val : data.entrySet()) {
System.out.println(val);
}
// Cat=猫
// Dog=犬
// Monkey=サル
LinkedHashMap
LinkedHashMapは、順序を管理することができます。
HashMapの次に使用頻度が高いMapです。
宣言は以下の通りです。
Map<String, String> data = new LinkedHashMap<>();
それでは、実際のサンプルコードを見ていきましょう。
Map<String, String> data = new LinkedHashMap<>();
// データの格納
data.put("Monkey", "サル");
data.put("Dog", "犬");
data.put("Cat", "猫");
// データの取り出し
for (var val : data.entrySet()) {
System.out.println(val);
}
// Monkey=サル
// Dog=犬
// Cat=猫
LinkedHashMapにすると、データを格納した順番になりました。
拡張for文で順番に取り出したいときは、LinkedHashMapの方が便利ですね!
他にも、様々な実装型がありますが、今回はこのくらいにしておきます。
サンプルコード
最後にMapを使ったサンプルコードを紹介します。
以下のサンプルコードは、Mapのキーと同じ文字列のものを取り出すコードです。
このコードを拡張すれば、必要なものだけ取り出すこともできます。
package java20230603;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Sample1 {
public static void main(String[] args) {
// Mapの宣言
Map<String, String> data = new HashMap<>();
// データの格納
data.put("Monkey", "サル");
data.put("Dog", "犬");
data.put("Cat", "猫");
// keyを格納
List<String> keyList = new ArrayList<>();
for (var val : data.keySet()) {
keyList.add(val);
}
// 偽データを格納
keyList.add("fakeData");
// keyの値がある場合は値を出力、ない場合は第2引数の文字列を出力
for (var val : keyList) {
System.out.println(data.getOrDefault(val, val + "は対象無し"));
}
// 実行結果
// サル
// 猫
// 犬
// fakeDataは対象無し
}
}
まとめ
Mapは便利ですが、思わぬバグに遭遇することもあります。
そのため、自分がやりたいこと(用途)によって実装型を選別する必要があります。
個人的にはLinkedHashMapがかっこいいので好きです(笑)
ただ、TreeMapも拡張すればかなり便利ですね!
今回紹介した実装型以外にもまだまだありますので、
気になる方は調べたり、書籍を購入して勉強するのもおススメです。
コメント