Mapとは何か?
メニューを表示するにはスワイプしてください
JavaにおけるMapインターフェースについて説明。
MapインターフェースはJavaコレクションフレームワークの一部であり、キーと値のペアの形式でデータを扱うためのメソッドを定義。
定義を見てみる:
このようなデータ構造の主な実装は、JavaのHashMapであり、Mapインターフェースを実装。
この実装の主なメソッドと動作原理について解説。
まずは宣言とメソッドから:
Main.java
1Map<K, V> map = new HashMap<>();
ここでは、ジェネリクスまたはダイヤモンドブラケット内に2つの値が指定されていることがわかります。
- 値
Kはキーのデータ型を表します。 - 値
Vは値のデータ型を表します。
このように、このデータ構造を宣言する際に、キーと値のデータ型を指定します。
次に、Map インターフェースで定義されているメソッドを確認します。
メソッド
V put(K key, V value): この Map で指定されたキーに指定された値を関連付けます。Map に以前からそのキーのマッピングが存在する場合、古い値は置き換えられます。
Main.java
1234567891011121314package com.example; import java.util.HashMap; import java.util.Map; public class Main { public static void main(String[] args) { Map<Integer, String> map = new HashMap<>(); map.put(1, "One"); map.put(2, "Two"); map.put(3, "Three"); System.out.println(map); } }
V get(Object key): 指定されたキーに関連付けられた値を返し、この null にそのキーのマッピングが存在しない場合は Map を返す。
ここでは、取得したい値に対応するキーを指定する。
キー 2 に対応する値を取得:
Main.java
12345678910111213141516package com.example; import java.util.HashMap; import java.util.Map; public class Main { public static void main(String[] args) { Map<Integer, String> map = new HashMap<>(); map.put(1, "One"); map.put(2, "Two"); map.put(3, "Three"); System.out.println("Map: " + map); String value = map.get(2); System.out.println("Value: " + value); } }
-
boolean containsKey(Object key): 指定されたキーに対するマッピングがtrueに存在する場合はMapを返す; -
boolean containsValue(Object value): 指定された値にマッピングされた1つ以上のキーがtrueに存在する場合はMapを返す。
これら2つのメソッドは関連性があり、指定した Map に目的のキーや値が含まれているかを判定するのに役立つ。これらのメソッドは boolean 値を返すため、条件式として利用するのに便利。
例を見てみよう:
Main.java
12345678910111213141516171819202122232425package com.example; import java.util.HashMap; import java.util.Map; public class Main { public static void main(String[] args) { Map<Integer, String> map = new HashMap<>(); map.put(1, "One"); map.put(2, "Two"); map.put(3, "Three"); System.out.println("Map: " + map); if (map.containsKey(2)) { System.out.println("Value with key 2: " + map.get(2)); } else { System.out.println("There is no value with key 2!"); } if (map.containsValue("Four")) { System.out.println(map.get(4)); } else { System.out.println("There is no key with value \"Four\"!"); } } }
上記の例では、Map内でキーの存在および値の存在を確認しています。値が見つかった場合は、それらをコンソールに表示します。該当する値がない場合は、そのデータが存在しないことを示すメッセージを出力します。
-
boolean isEmpty(): このtrueにキーと値のペアが存在しない場合にMapを返します。 -
V remove(Object key): 指定されたキーに対応するマッピングをこのMapから削除し、以前の値を返します。
他のデータ構造と同様に、Mapから要素を削除することができます。
Main.java
12345678910111213141516package com.example; import java.util.HashMap; import java.util.Map; public class Main { public static void main(String[] args) { Map<Integer, String> map = new HashMap<>(); map.put(1, "One"); map.put(2, "Two"); map.put(3, "Three"); System.out.println("Map: " + map); String removedElement = map.remove(3); System.out.println("Removed value: " + removedElement + ".\nMap after the removal operation: " + map); } }
したがって、要素はキーによって削除可能。
マップ管理の基本メソッド
次に、すでに馴染みのあるメソッドを例なしで列挙。 また、興味深いメソッドも残っている。
まずは基本から:
-
void clear(): このMapからすべての要素を削除; -
int size(): このMap内のキーと値のマッピング数を返す; -
void putAll(Map<? extends K, ? extends V> m): 指定されたMapからすべてのマッピングをこのMapにコピー。
次に、Mapから値(またはキー)のコレクションを返すメソッドに進む。つまり、データ構造から値(またはキー)のみを格納するキー・バリュー構造を取得。
例えば、ArrayList<>。
Main.java
12345678910111213141516package com.example; import java.util.*; public class Main { public static void main(String[] args) { Map<Integer, String> map = new HashMap<>(); map.put(1, "One"); map.put(2, "Two"); map.put(3, "Three"); System.out.println("Map: " + map); Collection<String> list; list = map.values(); System.out.println("Values" + list); } }
ここで、Mapから値のコレクションを取得。
このコレクションをArrayListに転送可能。
Main.java
123456789101112131415161718package com.example; import java.util.*; public class Main { public static void main(String[] args) { Map<Integer, String> map = new HashMap<>(); map.put(1, "One"); map.put(2, "Two"); map.put(3, "Three"); System.out.println("Map: " + map); Collection<String> collection; collection = map.values(); System.out.println("Values" + collection); List<String> arrayList = new ArrayList<>(collection); System.out.println("ArrayList: " + arrayList); } }
ArrayListから値を使ってMapを初期化。
また、Mapからキーを取得するメソッドも存在。これらのキーはSetという構造で返される。Setについてはここでは詳しく説明しないが、重複しない値のみを保持するデータ構造。
このメソッドを確認:
Set<K> keySet(): このSetに含まれるキーのMapビューを返す。
Main.java
12345678910111213141516package com.example; import java.util.*; public class Main { public static void main(String[] args) { Map<Integer, String> map = new HashMap<>(); map.put(1, "One"); map.put(2, "Two"); map.put(3, "Three"); System.out.println("Map: " + map); Set<Integer> keys; keys = map.keySet(); System.out.println("Keys: " + keys); } }
このようにして、Mapからすべてのキーのセットも取得可能。
これでメソッドの説明は終了。次に、Mapの使用方法と実際の例について確認:
Mapの使用例
キーと値の構造は多くの実用的な用途が存在。最も単純な例として、学生の成績管理システムを考察。
ここでは、キーが Map 型(学生名を表す)、値が String 型(学生の成績を表す)となるIntegerを作成。この構造により、学生ごとに成績を割り当て、キーを使って特定の学生の成績を簡単に取得可能:
Main.java
12345678910111213141516package com.example; import java.util.*; public class Main { public static void main(String[] args) { Map<String, Integer> studentsGrades = new HashMap<>(); studentsGrades.put("Bob", 9); studentsGrades.put("Alice", 8); studentsGrades.put("Mike", 5); studentsGrades.put("John", 10); studentsGrades.put("Martin", 7); studentsGrades.put("Peter", 5); System.out.println("Student's grades: " + studentsGrades); } }
ここで、Mike と Alice の成績を取得し、それらを比較する必要があるとします。これは、上記で学んだメソッドを使って簡単に実現できます。次のコードで実装してみましょう。
Main.java
123456789101112131415161718192021package com.example; import java.util.*; public class Main { public static void main(String[] args) { Map<String, Integer> studentsGrades = new HashMap<>(); studentsGrades.put("Bob", 9); studentsGrades.put("Alice", 8); studentsGrades.put("Mike", 5); studentsGrades.put("John", 10); studentsGrades.put("Martin", 7); studentsGrades.put("Peter", 5); System.out.println("Student's grades: " + studentsGrades); Integer mikeGrade = studentsGrades.get("Mike"); Integer aliceGrade = studentsGrades.get("Alice"); System.out.println(mikeGrade.compareTo(aliceGrade) == -1 ? "Alice's grade is higher": "Mike's grade is higher"); } }
ここでは、三項演算子 と compareTo() ラッパークラスの Integer メソッドが使用されています。もしこの動作が分かりにくい場合、次のように説明できます。
Main.java
12345678910111213141516171819202122232425package com.example; import java.util.*; public class Main { public static void main(String[] args) { Map<String, Integer> studentsGrades = new HashMap<>(); studentsGrades.put("Bob", 9); studentsGrades.put("Alice", 8); studentsGrades.put("Mike", 5); studentsGrades.put("John", 10); studentsGrades.put("Martin", 7); studentsGrades.put("Peter", 5); System.out.println("Student's grades: " + studentsGrades); Integer mikeGrade = studentsGrades.get("Mike"); Integer aliceGrade = studentsGrades.get("Alice"); if (mikeGrade.compareTo(aliceGrade) == -1) { System.out.println("Alice's grade is higher"); } else { System.out.println("Mike's grade is higher"); } } }
それでは、7より高い成績のすべての学生を集める(7は含まない)ように求められた場合を考えてみましょう。これは興味深い課題となり、これをどのように実現するかを説明します。
Mapの反復処理
JavaのMap内の要素を反復処理するには、Mapインターフェースおよびその実装が提供するさまざまな方法を利用できます。以下は、Mapを反復処理するいくつかの方法です。
キーの反復処理(keySet()):keySet()メソッドは、Map内のすべてのキーのセットを返します。このセットを使ってキーを反復処理し、対応する値を取得できます。
Main.java
12345678910111213141516package com.example; import java.util.*; public class Main { public static void main(String[] args) { Map<String, Integer> map = new HashMap<>(); map.put("Key1", 1); map.put("Key2", 2); for (String key : map.keySet()) { Integer value = map.get(key); System.out.println("Key: " + key + ", Value: " + value); } } }
値の反復処理(values()):values() メソッドは Map 内のすべての値のコレクションを返します。このコレクションを利用して値を反復処理できます。
Main.java
123456789101112131415package com.example; import java.util.*; public class Main { public static void main(String[] args) { Map<String, Integer> map = new HashMap<>(); map.put("Key1", 1); map.put("Key2", 2); for (Integer value : map.values()) { System.out.println("Value: " + value); } } }
キーと値のペアの反復(entrySet()):entrySet() メソッドは、キーと値のペアを表す Map.Entry オブジェクトのセットを返します。これにより、ペアごとに直接反復処理が可能です。
Main.java
1234567891011121314151617package com.example; import java.util.*; public class Main { public static void main(String[] args) { Map<String, Integer> map = new HashMap<>(); map.put("Key1", 1); map.put("Key2", 2); for (Map.Entry<String, Integer> entry : map.entrySet()) { String key = entry.getKey(); Integer value = entry.getValue(); System.out.println("Key: " + key + ", Value: " + value); } } }
この点についてもう少し詳しく見ていきます。最初は非常に複雑に感じるかもしれませんが、仕組みの詳細を理解する必要はありません。構文は常に同じだからです。
Map.Entry<K, V> entry : map.entrySet()
entry オブジェクトを使うことで、Map 内のキーと値の両方に同時にアクセスできます。ここで、先ほどの課題をentry setを使って解決してみましょう。7より高い成績の学生をすべて取得します。そのために、entry.getValue() でチェックし、条件に合う学生が見つかった場合、事前に作成した ArrayList にそのキーを格納します。
Main.java
1234567891011121314151617181920212223242526package com.example; import java.util.*; public class Main { public static void main(String[] args) { Map<String, Integer> studentsGrades = new HashMap<>(); studentsGrades.put("Bob", 9); studentsGrades.put("Alice", 8); studentsGrades.put("Mike", 5); studentsGrades.put("John", 10); studentsGrades.put("Martin", 7); studentsGrades.put("Peter", 5); System.out.println("Student's grades: " + studentsGrades); List<String> studentsWithGradeHigherThanSeven = new ArrayList<>(); for (Map.Entry<String, Integer> entry : studentsGrades.entrySet()) { if (entry.getValue() > 7) { studentsWithGradeHigherThanSeven.add(entry.getKey()); } } System.out.println(studentsWithGradeHigherThanSeven); } }
このようにして、Map を反復処理し、試験に合格した目的の学生リストを見つけることができます。
エントリーセットは、非常に便利なツールであり、ループを使って Map をさまざまな方法で反復処理し、キーと値の両方にアクセスできるようにします。
次の章では、この章で積極的に使用した HashMap が実際にどのように動作するのかを詳しく見ていきます。
1. Java でキーと値のペアのコレクションを表すインターフェースはどれですか?
2. for-eachループを使用してMap内のすべてのキーをどのように反復処理しますか?
3. values()におけるMapメソッドの目的は何ですか?
4. Mapで特定のキーが存在するかどうかを確認するために使用されるメソッドはどれですか?
5. JavaのMapからキーと値のペアを削除するために使用されるメソッドはどれですか?
フィードバックありがとうございます!
AIに質問する
AIに質問する
何でも質問するか、提案された質問の1つを試してチャットを始めてください