Javaのマップ(Map)について


Javaのマップはキーと値とのペアの集まりを管理するオブジェクトです。Mapのようにキーと値の型を<>の中に指定します。

Map map = new HashMap<>();

😎 Mapインターフェースのメソッド

Mapインターフェースの代表的なメソッドは次のとおりです。

メソッド名 説明
containsKey 指定したキーの存在チェック
containsValue 指定した値の存在チェック
entrySet 要素全体をなめるためのMap.Entryセットを返す
forEach 要素ごとに指定処理を実行
get 指定したキーで値を検索
getOrDefault 指定したキーで値を検索し、値がなければデフォルト値を返す
keySet キーの集合を取得
merge 指定したキーの既存要素を使って新要素を追加
put 要素(キーと値のペア)を追加
putAll 要素をまとめて追加
remove 要素の削除
replace 指定したキーの値を置換
replaceAll 要素を置換
size 要素数の取得
values 値の集合を取得

🐞 Mapインターフェースを実装する具象クラス

Mapインターフェースを実装する主な具象クラスHashMapLinkedHashMapTreeMapを紹介します。

HashMap

HashMapの特徴は次のとおりです。

  • 内部に配列を確保して、ハッシュ関数を介したキーと値とのペアを格納
  • キーをハッシュ値から生成するため、順序は不定となります
  • ハッシュ関数の衝突は性能低下を招くため、適切なハッシュ表のサイズを指定すべき
public class MapSample {
public static void main(String[] args) {
Map map = new HashMap<>();
map.put("hoge", "zero");
map.put("fuga", "one");
map.put("pugi", "two");
System.out.println(map.get("fuga")); //=> oneを出力
System.out.println(map); //=> {pugi=two, hoge=zero, fuga=one}
}
}

LinkedHashMap

LinkedHashMapの特徴は次のとおりです。

  • ハッシュ表とLinkedListと同じリンクリストを内部に保持します
  • 要素を追加するとハッシュ表とリンクリスト両方に要素を追加します
  • 要素の取得では、ハッシュ表を介して要素を検出します
  • 要素を列挙する際はリンクリストにしたがって、要素の追加順に出力されます
public class MapSample {
public static void main(String[] args) {
Map map = new LinkedHashMap<>();
map.put(0, "zero");
map.put(1, "one");
map.put(2, "two");
System.out.println(map.get(1)); //=> oneを出力
System.out.println(map); //=> {0=zero, 1=one, 2=two}
}
}

TreeMap

TreeMapの特徴は次のとおりです。

  • 内部的には2分探索木の赤黒木でデータを格納します
  • 要素のキーが比較可能なことが条件です
  • キーがソートされた状態でデータが格納されます
public class MapSample {
public static void main(String[] args) {
Map map = new TreeMap<>();
map.put(1, 1);
map.put(40, 2);
map.put(70, 3);
map.put(100, 4);
map.put(3, 5);
map.put(2, 6);
map.put(8, 7);
map.put(6, 8);
map.put(9, 9);
map.put(5, 10);
System.out.println(map.get(100)); //=> 4
System.out.println(map); //=> {1=1, 2=6, 3=5, 5=10, 6=8, 8=7, 9=9, 40=2, 70=3, 100=4}
}
}

次の図は2分木からソート順のデータを取得する流れです。

出典:改訂2版 パーフェクトJava

NavigatableMap

NavigatableMapはキーの完全一致なくても、近いキーで検索できます。利用例は次のとおりです。

public class MyNavigatableMap {
public static void main(String... args) {
NavigatableMap map = new TreeMap<>();
map.put("ichi", "one");
map.put("ni", "two");
map.put("san", "three");

// 指定したキーと一致もしくは、より大きく一番近いキーのエントリを返す
Map.Entry entry = map.ceilingEntry("ic");
if (entry != null) {
System.out.println(entry.getKey() + ": " + entry.getValue()); //=> "ichi: one"
}
}
}

🚜 マップの実装クラスの使い分け

  • 順序が不要な場合はHashMap
  • 追加した順序が欲しい場合はLinkedHashMap
  • ソートされた順序が欲しい場合はTreeMap

🍄 参考リンク

🖥 VULTRおすすめ

VULTR」はVPSサーバのサービスです。日本にリージョンがあり、最安は512MBで2.5ドル/月($0.004/時間)で借りることができます。4GBメモリでも月20ドルです。 最近はVULTRのヘビーユーザーになので、「ここ」から会員登録してもらえるとサービス開発が捗ります!

📚 おすすめの書籍