こんにちは!今日は、Map に関する最も一般的な質問に答えますが、まず、Map が何であるかを思い出してみましょう。 マップは、一連のキーと値のペアを含むデータ構造です。データ構造が辞書に似ているため、そのように呼ばれることがよくあります。同時に、Map はインターフェースであり、標準の JDK には、Hashmap、LinkedHashMap、Hashtable、TreeMap などの主要な実装が含まれています。最もよく使用される実装は Hashmap なので、例ではそれを使用します。マップの標準的な作成と塗りつぶしは次のようになります。
Map<Integer, String> map = new HashMap<>();
map.put(1, "string 1");
map.put(2, "string 2");
map.put(3, "string 3");
そして、これはキーによって値を取得する方法です:
String string1 = map.get(1);
String string2 = map.get(2);
String string3 = map.get(3);
上記の内容がすべて明らかであれば、よくある質問への回答に進みましょう。
0. すべての Map 値を反復処理する方法
値の反復処理は、マップで実行する最も一般的な操作です。すべてのキーと値のペアは内部 Map.Entry インターフェイスに保存されており、それらを取得するには、 を呼び出す必要がありますentrySet()
。ループできるペアのセットを返します。
for(Map.Entry<Integer, String> entry: map.entrySet()) {
// get key
Integer key = entry.getKey();
// get value
String value = entry.getValue();
}
Или используя итератор:
Iterator<Map.Entry<Integer, String>> itr = map.entrySet().iterator();
while(itr.hasNext()) {
Map.Entry<Integer, String> entry = itr.next();
// get key
Integer key = entry.getKey();
// get value
String value = entry.getValue();
}
1. マップをリストに変換する方法
Map インターフェイスには、要素のリストを返す 3 つのメソッドがあります。- keySet() - キーのセットを返します。
- value() - 値のコレクションを返します。
- entrySet() - キーと値のセットのセットを返します。
ArrayList
、 Collection 型の引数を持つコンストラクターがあることがわかります。Set は Collection の子孫であるため、上記のすべてのメソッドの結果をクラスのコンストラクターに渡すことができますArrayList
。したがって、新しいリストを作成し、次の値を入力しますMap
。
// key list
List<Integer> keyList = new ArrayList<>(map.keySet());
// value list
List<String> valueList = new ArrayList<>(map.values());
// key-value list
List<Map.Entry<Integer, String>> entryList = new ArrayList<>(map.entrySet());
2. マップキーのソート方法
マップの並べ替えも、プログラミングではかなり一般的な操作です。これはいくつかの方法で行うことができます。-
Map.Entry をリストに追加し、Comparator を使用して並べ替えます。
コンパレーターでは、ペアのキーのみを比較します。
List
> list = new ArrayList(map.entrySet()); Collections.sort(list, new Comparator<Map.Entry<Integer, String>>() { @Override public int compare(Map.Entry<Integer, String> o1, Map.Entry<Integer, String> o2) { return o1.getKey() - o2.getKey(); } }); ラムダを理解していれば、このエントリは大幅に短縮できます。
Collections.sort(list, Comparator.comparingInt(Map.Entry::getKey));
-
を使用します
SortedMap
。より正確には、TreeMap
そのコンストラクターで Comparator を受け取るその実装を使用します。このコンパレータはマップ キーに適用されるため、キーはインターフェイスを実装するクラスである必要がありますComparable
。SortedMap<Integer, String> sortedMap = new TreeMap<>(new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { return o1 - o2; } });
そしてもちろん、ラムダを使用してすべてを書き直すことができます。
SortedMap<Integer, String> sortedMap = new TreeMap<>(Comparator.comparingInt(o -> o));
最初の方法とは異なり、SortedMap を使用すると、データは常に並べ替えられた形式で保存されます。
3. マップ値をソートする方法
ここでは、キーの最初のアプローチと同様のアプローチを使用する必要があります。値のリストを取得し、リスト内で並べ替えます。
List <Map.Entry<Integer, String>> valuesList = new ArrayList(map.entrySet());
Collections.sort(list, new Comparator<Map.Entry<Integer, String>>() {
@Override
public int compare(Map.Entry<Integer, String> o1, Map.Entry<Integer, String> o2) {
return o1.getValue().compareTo(o2.getValue());
}
});
そして、このラムダは次のようになります。
Collections.sort(list, Comparator.comparing(Map.Entry::getValue));
4. HashMap、TreeMap、および Hashtable の違いは何ですか
前述したように、Map インターフェイスには主に 3 つの実装があります。それぞれに独自の特徴があります。-
要素の順序。
HashMap
また、Hashtable
アイテムが追加された順序で保存されることを保証するものではありません。さらに、要素の順序が時間の経過とともに変化しないことも保証されません。さらに、TreeMap
要素が追加された順序で、または指定されたコンパレータに従って格納されることが保証されます。 -
有効な値。
HashMap
キーと null 値を持つことができます。HashTable
いいえ。TreeMap は、コンパレータが許可する場合にのみ null 値を使用できます。コンパレータを使用しない場合 (追加された順序でペアを格納することにより)、null は許可されません。 -
同期。同期のみ
HashTable
が行われ、残りは同期されません。マップが別のスレッドからアクセスされない場合は、HashTable の代わりに HashMap を使用することをお勧めします。
ハッシュマップ | ハッシュ表 | ツリーマップ | |
---|---|---|---|
要素の順序 | いいえ | いいえ | はい |
値として null | はい | いいえ | あまり |
スレッドの安全性 | いいえ | はい | いいえ |
要素検索のアルゴリズムの複雑さ | ○(1) | ○(1) | O(log n) |
内部のデータ構造 | ハッシュ表 | ハッシュ表 | 赤黒の木 |
5. 双方向マップの作成方法
場合によっては、キーと値の両方が一意になる、つまりマップにキーとキーのペアが含まれるデータ構造を使用することが必要になることがあります。このデータ構造により、地図上に「反転表示/検索」を作成できます。つまり、その値によってキーを見つけることができます。このデータ構造は双方向マップと呼ばれますが、残念ながら JDK ではサポートされていません。しかし、幸いなことに、その実装は Apache Common Collections または Guava ライブラリにあります。そこでは、それぞれ BidiMap および BiMap と呼ばれます。これらの実装では、キーと値の一意性に制限が課されます。これにより、1 対 1 の関係が作成されます。6. 空のマップの作成方法
空のマップを作成するには 2 つの方法があります。-
通常のオブジェクトの初期化:
Map<Integer, String> emptyMap = new HashMap<>();
-
不変の空のマップを作成します。
Map<Integer, String> emptyMap = Collections.emptyMap();
UnsupportedOperationException
次の例外が発生します。この記事では、Map インターフェイスを使用するときに発生する可能性のある最も一般的な質問について検討しました。
GO TO FULL VERSION