java.utilパッケージに分類されるコレクションフレームワーク「List」「Map」「Set」の中のMapについての説明記事です。
この記事内のクラスはジェネリクスを使用してます。
種類 | 概要 |
---|---|
List | 配列に近い構造を持っている。要素を番号で管理する。 |
Map | 要素にキー(要素を区別する値)を付けて管理する。キーの重複は不可。 |
Set | 要素に順番はなく、要素の重複を許可しない。 |
Mapはインタフェースとして定義されており、Mapインタフェースを実装するクラスがあります。
Mapインタフェース | |
---|---|
実装クラス | 概要 |
HashMap | キーで値を管理する。キーの重複は不可でかつ順序は不定となっている。 |
TreeMap | HashMapと同様にキーで値を管理する。キーは重複が不可で、キーを自然順序で管理する。 |
もくじ
Mapオブジェクトのイメージ
Mapは配列やListとは違い、番号で要素を管理するのではなく、「キー」と「値」をセットにして要素を管理しています。
具体的には以下のようなイメージとなります。以下の図は「キーを文字列」「値を文字列」としている例です。
Mapオブジェクトはキーで値を取得するという方法を用います。例えば、”佐藤”の値を取得する場合は”さとう”のキーを用いて取得を行います。
例えば、以下のように記述した場合、出力は”佐藤”となります。
System.out.println(map.get(“さとう”));
HashMapのインスタンス生成と特徴
HashMapは前述の通り、キーとバリュー(値)をセットにして管理を行います。配列やListとは違った管理の仕方を行います。以下の仕様はTreeMapも同様です。
- キーで管理を行うため、値を追加する際にはキーも必須となる
- 値の取り出しもキーで行う
- 番号順に取り出せないため、通常のforやwhileでループ処理ができない
- 値の重複は許可されていないため、同じキーで追加する場合は値が上書きされる
HashMapの インスタンス生成 |
Map<キーの型 , バリューの型> インスタンス変数名 = new HashMap<キーの型 , バリューの型>() ; |
---|---|
記述例 | Map<String , String> map = new HashMap<String , String>() ;
Map<String , StringBuffer> name_map = new HashMap<String , StringBuffer>() ; |
宣言する型はMapインターフェイスになっていますが「HashMap<String , String> map」や「HashMap<String , StringBuffer> name_map」という記述でも宣言可能です。
TreeMapのインスタンス生成と特徴
TreeMapはHashMapとほぼ同等の利用ができますが、値が自然順序で並びます。
TreeMapの インスタンス生成 |
Map<キーの型 , バリューの型> インスタンス変数名 = new TreeMap<キーの型 , バリューの型>() ; |
---|---|
記述例 | Map<String , String> map = new TreeMap<String , String>() ;
Map<String , StringBuffer> name_map = new TreeMap<String , StringBuffer>() ; |
宣言する型はMapインターフェイスになっていますが「TreeMap<String , String> map」や「TreeMap<String , StringBuffer> name_map」という記述でも宣言可能です。
HashMapおよびTreeMapのメソッドを利用してデータを扱う
HashMapおよびTreeMapはMapインタフェースで定義されている共通のメソッドが基本のメソッドとなります。TreeMapは順序が存在するため、その順序を利用したメソッドも定義されています。
戻り値の型や引数部分のK(Key)とV(Value)はジェネリクスで指定したキーとバリューの型です。例えば「Map<String , StringBuffer>」の場合はKを全てStringに、Vを全てStringBufferに置き換えてください。
下の表はHashMapとTreeMapで共通のメソッドのみ紹介しています。
メソッド名 | 戻り値の型 | 引数 | 処理内容 |
---|---|---|---|
put | V | K key , V value |
指定された値を指定したキーと紐づけて追加します。 |
clear | void | なし | マップ内の値を全て削除します。 |
get | V value | Object key | 引数で指定したキーに紐づいた値を戻り値で取得できます。 |
remove | V value | Object key | マップからキーおよび紐づいた値を削除します。
戻り値は削除した値です。 |
remove | boolean | Object key, Object value | 指定された値にキーが紐づいている場合のみ削除します。 |
size | int size | なし | マップ内の数を戻り値で取得できます。 |
マップ サンプルプログラム
以下のプログラムを「Number51.java」という名前でWorkフォルダ内に保存します。
保存が完了したら、コマンドプロンプトを起動し、Number51.javaをコンパイルしてみましょう。※プログラムが長いため、必要に応じてコピペで確認してください
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
//java.utilパッケージなのでインポートが必要 import java.util.HashMap; import java.util.Map; class Number51{ public static void main(String[] args){ Map<String , String> map = new HashMap<String , String>(); /* コレクションに格納 ひらがなをkey、漢字をvalueにしている */ map.put("たなか","田中"); map.put("さとう","佐藤"); map.put("すずき","鈴木"); System.out.println(map.get("たなか")); //たなかのキーで取得 System.out.println(map.get("すずき")); //すずきのキーで取得 map.put("しみず","清水"); System.out.println("マップ内には" + map.size() + "個の要素があります"); //キーは重複不可の為、値が置き換わる map.put("たなか" , "田仲"); System.out.println(map.get("たなか")); //たなかのキーで取得 System.out.println("マップ内には" + map.size() + "個の要素があります"); //マップ内を簡易確認 System.out.println(map); } } |
実行例
C:\work>javac Number51.java
C:\work>java Number51
田中
鈴木
マップ内には4個の要素があります
田仲
マップ内には4個の要素があります
{すずき=鈴木, さとう=佐藤, しみず=清水, たなか=田仲}
補足 Map内のデータをループ処理するには
Map内のデータは配列のように番号管理されていないため、配列やListのように番号を利用したループ処理を行うことができません。
Mapは「キー」と「値」のセットをコレクション(集める)オブジェクトの為、キーの集合をループで扱うのか、値の集合をループで扱うのかを考える必要があります。さらに、キーと値をセットにしてループさせることも可能です。
Map内のデータをループ処理するにはいくつかの方法があります。
キーと値をどちらもループで扱う場合
1.キーが格納されている配列やListを別途用意しておき、組み合わせてループを行う
ループはキーと同様のデータが格納されている配列を利用して、配列のデータ(キー)を利用して値を取得する。
2.entrySet()メソッドを利用してMap.Entry<K,V>が格納されているSetオブジェクトを取得し、ループを行う
MapオブジェクトからMap.Entry<K,V>が格納されているSetオブジェクトを取得。そのあと、Setオブジェクトをループさせてキーと値を取得する。
キーをループで扱う場合
3.keySet()メソッドを利用してキーが格納されているSetオブジェクトを取得し、ループを行う
keySet()メソッドを利用して、キーが格納されているSetオブジェクトを取得。そのSetオブジェクトを利用してループ処理を行う。
値をループで扱う場合
4.values()メソッドを利用して値が格納されているCollectionオブジェクトを取得し、ループを行う
values()メソッドを利用して、値が格納されているSetオブジェクトを取得。そのSetオブジェクトを利用してループ処理を行う。
ループに関連するメソッド
メソッド名 | 戻り値の型 | 引数 | 処理内容 |
---|---|---|---|
entrySet | Set<Map.Entry<K , V>> | なし | Map.Entry<K,V>型のデータを格納したSetオブジェクトを取得できる。 |
keySet | Set<K> | なし | キーが格納されているSetオブジェクトを取得できる。 |
values | Collection<V> | なし | 値が格納されているCollectionオブジェクトを取得できる。 |
Mapとループ サンプルプログラム
以下のプログラムを「Number52.java」という名前でWorkフォルダ内に保存します。
保存が完了したら、コマンドプロンプトを起動し、Number52.javaをコンパイルしてみましょう。※プログラムが長いため、必要に応じてコピペで確認してください
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
//java.utilパッケージなのでインポートが必要 import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.Collection; class Number52{ public static void main(String[] args){ Map<String , String> map = new HashMap<String , String>(); /* コレクションに格納 ひらがなをkey、漢字をvalueにしている */ map.put("たなか","田中"); map.put("さとう","佐藤"); map.put("すずき","鈴木"); map.put("しみず","清水"); map.put("えんどう","遠藤"); /******** 1.キーが格納されている配列やListを別途用意しておき、組み合わせてループを行う *********/ String[] keys = {"たなか","さとう","すずき","しみず","えんどう"}; for(int i = 0; i < keys.length; i++){ System.out.print("キー:" + keys[i] + "、値:"); System.out.println(map.get(keys[i])); } System.out.println("------"); /******** 2.entrySet()メソッドを利用してMap.Entry<K,V>が格納されているSetオブジェクトを取得し、ループを行う *********/ //Map.Entry<K,V>が格納されているSetオブジェクトを取得 Set<Map.Entry<String , String>> obj01 = map.entrySet(); //拡張forを利用してSetオブジェクトをループ処理 for(Map.Entry e : obj01){ System.out.print("キー:" + e.getKey() + "、値:"); System.out.println(e.getValue()); } System.out.println("------"); /******** 3.keySet()メソッドを利用してキーが格納されているSetオブジェクトを取得し、ループを行う *********/ //キーが格納されているSetオブジェクトを取得 Set<String> obj02 = map.keySet(); //拡張forを利用してSetオブジェクトをループ処理 for(String s : obj02){ System.out.println("キー:" + s); } System.out.println("------"); /******** 4.values()メソッドを利用して値が格納されているCollectionオブジェクトを取得し、ループを行う *********/ //values()メソッドを利用して値が格納されているCollectionオブジェクトを取得 Collection<String> obj03 = map.values(); //拡張forを利用してCollectionオブジェクトをループ処理 for(String s : obj03){ System.out.println("値:" + s); } } } |
実行例
C:\work>javac Number52.java
C:\work>java Number52
キー:たなか、値:田中
キー:さとう、値:佐藤
キー:すずき、値:鈴木
キー:しみず、値:清水
キー:えんどう、値:遠藤
——
キー:えんどう、値:遠藤
キー:すずき、値:鈴木
キー:さとう、値:佐藤
キー:しみず、値:清水
キー:たなか、値:田中
——
キー:えんどう
キー:すずき
キー:さとう
キー:しみず
キー:たなか
——
値:遠藤
値:鈴木
値:佐藤
値:清水
値:田中
マップ 復習問題
- HashMapについての説明で誤っているものを選んでください
- 解答群
- キーは重複不可である
- キーの自然順序で管理する
- 値をキーで管理する
- 同じキーを利用すると値が上書きされる
- TreeMapについての説明で誤っているものを選んでください
- 解答群
- キーは重複不可である
- HashMapのメソッドとは名称も種類も全く別のものしか利用できない
- Mapインターフェイスを実装している
- 同じキーで値を追加すると値が上書きされる
- put(K key , V value)メソッドの説明として誤っているものを選んでください
- 解答群
- 引数にはジェネリクスで指定した型のデータを指定する
- 戻り値はない
- キーは第一引数に指定する
- 値は第二引数に指定する
- get(K key)メソッドの説明として誤っているものを選んでください
- 解答群
- 戻り値がある
- 指定したキーに対応する値が取得できる
- 指定した値に対応するキーが取得できる
- 指定した引数に対応するデータがない場合は、nullが戻り値となる
- Mapオブジェクトをループさせる説明として誤っているものを選んでください
- 解答群
- entrySet()メソッドで取得したオブジェクトは、キーも値もループで取得できる
- keySet()メソッドで取得したオブジェクトは、キーをループで取得できる
- values()メソッドで取得したオブジェクトは、値をループで取得できる
- keySet()メソッドとvalues()メソッドの戻り値の型は同じである
- お疲れ様でした。
まとめ
-
- マップは値をキーで管理する
- 値を取得する際はキーを利用する
- キーの重複は不可となっており、キーが同一値が上書きされる
- メソッドを利用して要素の追加、削除、取得等が可能