やあ!このレッスンでは、 Java HashMapを詳しく見ていきます。以前、要素がそれ自体として保存されるデータ構造について研究しました。配列またはArrayList / LinkedListには、いくつかの要素を格納します。しかし、私たちのタスクが少し変わったらどうなるでしょうか?
次のタスクを想像してください。各人の名前とパスポート番号を保存する 100 人のリストを作成します。原理的には、これはそれほど難しいことではありません。たとえば、両方を文字列に詰め込んで、 「Amelia Aguilar, 4211 717171」という文字列のリストを作成できます。 しかし、この解決策には 2 つの欠点があります。まず、パスポート番号で検索する機能が必要になる場合があります。そして、この情報保存形式を考えると、これは問題になります。第二に、同じパスポート番号を持つ 2 人の異なる人物を作成することを妨げるものはありません。そして、これが私たちのソリューションの最も深刻な欠点です。これは決して許されるべきではありません。同じパスポート番号を持つ人は 2 人もいません。新しいデータ構造が役に立ちます: Map。「連想配列」としても知られていますが、この用語はあまり使用されません。より一般的には、「辞書」または「地図」と呼ばれます。:) これは、以前に検討したデータ構造と根本的にどう違うのでしょうか? 何よりも、Map 内のデータはキーと値のペアとして保存されるという事実にあります。数値、文字列、他のクラスのオブジェクトなど、あらゆるものをキーと値として使用できます。今日は、 Mapクラスの最も一般的な実装であるJava HashMapを学習します。
では、Java の HashMap について何を知っておく必要があるでしょうか?
作成は非常に簡単です。
public static void main(String[] args) {
HashMap<Integer, String> passportsAndNames = new HashMap<>();
}
ここでは、要素を「数値と文字列」のペアとして保存する辞書を作成します。数値はキーとして機能し、文字列は値として機能します。また、キーのタイプ (整数) と値のタイプ (文字列) を指定します。なぜ?まず、HashMapキーは常に一意です。パスポート番号をキーとして使用し、重複を避けることができるので、これは私たちにぴったりです。値はフルネームの文字列になります (異なる人が同じ名前を持つことができます。それについては心配する必要はありません)。HashMapに新しいペアを追加すると、次のようになります。
public class Main {
public static void main(String[] args) {
HashMap<Integer, String> passportsAndNames = new HashMap<>();
passportsAndNames.put (212133, "Bridget Logan");
passportsAndNames.put (162348, "Ivan the Great");
passportsAndNames.put(8082771, "Donald John Trump");
System.out.println(passportsAndNames);
}
}
これにはput() メソッドを使用します。さらに、HashMap はtoString()メソッドをオーバーライドするので、コンソールに表示できるようになります。出力は次のようになります: {212133=Bridget Logan, 8082771=Donald John Trump, 162348=Ivan the Great} 次に、キーが本当に一意であるかどうかを確認してみましょう。マップ内で 既に使用されているキーを持つ新しい要素を追加してみましょう。
public static void main(String[] args) {
HashMap<Integer, String> passportsAndNames = new HashMap<>();
passportsAndNames.put (212133, "Bridget Logan");
passportsAndNames.put (162348, "Ivan the Great");
passportsAndNames.put(8082771, "Donald John Trump");
passportsAndNames.put(162348, "Albert Kent");// This key has already been used
System.out.println(passportsAndNames);
}
出力: {212133=Bridget Logan、8082771=Donald John Trump、162348=Albert Kent} ご覧のとおり、キー162348に関連付けられた以前の値は上書きされました。私たちが「キー」という用語を使用するのには理由があります。HashMap内の値にはキーを使用してアクセスしますが、その逆はできません。値は一意ではない可能性があるため、値を使用してキーを取得することはできません。これは、 HashMapから要素を取得または削除するときにはっきりとわかります。
public static void main(String[] args) {
HashMap<Integer, String> passportsAndNames = new HashMap<>();
passportsAndNames.put (212133, "Bridget Logan");
passportsAndNames.put (162348, "Ivan the Great");
passportsAndNames.put(8082771, "Donald John Trump");
String lidiaName = passportsAndNames.get(212133);
System.out.println(lidiaName);
passportsAndNames.remove(162348);
System.out.println(passportsAndNames);
}
値を取得するか、辞書からペアを削除するには、値に対応する一意のキーをget()とRemove()に渡す必要があります。配列やリストとは異なり、 Java のHashMapには数値インデックスがありません。値にはキーを使用してアクセスします。コンソール出力: Bridget Logan {212133=Bridget Logan, 8082771=Donald John Trump} ArrayListクラスとLinkedListクラスを使用すると、リストに特定の要素が含まれているかどうかを確認できます。 Java HashMap を使用すると、これを行うことができます。さらに、ペアの両方のメンバーに対してこれを行うことができます。これは、 containsKey () (キーのチェック) とcontainsValue()の内容です。(値をチェックする) メソッドです。
public static void main(String[] args) {
HashMap<Integer, String> passportsAndNames = new HashMap<>();
passportsAndNames.put (212133, "Bridget Logan");
passportsAndNames.put (162348, "Ivan the Great");
passportsAndNames.put(8082771, "Donald John Trump");
System.out.println(passportsAndNames.containsKey(11111));
System.out.println(passportsAndNames.containsValue("Donald John Trump"));
}
出力: false true Java の HashMap のもう 1 つの便利な機能は、すべてのキーとすべての値の個別のリストを取得できることです。これはkeySet()メソッドとvalue()メソッドを使用して実現されます。
public class Main {
public static void main(String[] args) {
HashMap<Integer, String> passportsAndNames = new HashMap<>();
passportsAndNames.put (212133, "Bridget Logan");
passportsAndNames.put (162348, "Ivan the Great");
passportsAndNames.put(8082771, "Donald John Trump");
Set keys = passportsAndNames.keySet();
System.out.println("Keys: " + keys);
ArrayList<String> values = new ArrayList<>(passportsAndNames.values());
System.out.println("Values: " + values);
}
}
キーはSetに抽出されますが、これについてはまだ説明していません。これは、繰り返し要素を含めることができないという点で特殊です。ここで重要なことは、すべてのキーのリストはHashMapから別のコレクションに取得できることを覚えておくことです。この例では、値を通常のArrayListに保存しました。コンソール出力: キー: [212133, 8082771, 162348] 値: [Bridget Logan、Donald John Trump、Ivan the Great] size() メソッド とclear ()メソッドは、これまでに説明した構造とまったく同じことを行います。最初の関数は現在辞書にある要素の数を返し、2 番目の関数はすべての要素を削除します。
public static void main(String[] args) {
HashMap<Integer, String> passportsAndNames = new HashMap<>();
passportsAndNames.put (212133, "Bridget Logan");
passportsAndNames.put (162348, "Ivan the Great");
passportsAndNames.put(8082771, "Donald John Trump");
System.out.println(passportsAndNames.size());
passportsAndNames.clear();
System.out.println(passportsAndNames);
}
出力: 3 {} HashMap に少なくとも 1 つの要素があるかどうかを確認するには、 isEmpty()メソッドを使用できます。
public static void main(String[] args) {
HashMap<Integer, String> passportsAndNames = new HashMap<>();
passportsAndNames.put (212133, "Bridget Logan");
passportsAndNames.put (162348, "Ivan the Great");
passportsAndNames.put(8082771, "Donald John Trump");
if (!passportsAndNames.isEmpty()) {
System.out.println(passportsAndNames);
}
}
出力: {212133=Bridget Logan、8082771=Donald John Trump、162348=Ivan the Great} ここでは、事前チェックの後にのみコンソールに出力します。:) もう 1 つの興味深い点は、2 つのマップを 1 つに結合できることです。これはputAll()メソッドを使用して実行されます。最初のHashMapでこれを呼び出し、2 番目の HashMap を引数として渡し、2 番目の要素が最初の HashMap に追加されます。
public static void main(String[] args) {
HashMap<Integer, String> passportsAndNames = new HashMap<>();
HashMap<Integer, String> passportsAndNames2 = new HashMap<>();
passportsAndNames.put (212133, "Bridget Logan");
passportsAndNames.put (162348, "Ivan the Great");
passportsAndNames.put(8082771, "Donald John Trump");
passportsAndNames2.put(917352, "Clifford Patrick");
passportsAndNames2.put(925648, "Mitchell Salgado");
passportsAndNames.putAll(passportsAndNames2);
System.out.println(passportsAndNames);
}
出力: {917352=Clifford Patrick, 212133=Bridget Logan, 8082771=Donald John Trump, 925648=Mitchell Salgado, 162348=Ivan the Great} PassportsAndNames2 のすべてのペアがPassportsAndNamesにコピーされました。次に、より複雑な例を考えてみましょう。具体的には、ループ内で HashMapを反復処理します。
for (Map.Entry<Integer, String> entry: passportsAndNames.entrySet()) {
System.out.println(entry);
}
Map.Entryクラスは、ディクショナリ内のキーと値のペアを示します。entrySet ()メソッドは、 HashMap内のすべてのペアのリストを返します。私たちのマップはこれらのMap.Entryペアで構成されているため、個別のキーや値ではなく、ペアに対して反復処理を行っています。出力: 212133=Bridget Logan 8082771=Donald John Trump 162348=Ivan the Great また、 HashMapに関するOracle の公式ドキュメント を必ず学習してください。
GO TO FULL VERSION