記事ディレクトリ
序文
学んだ知識を定着させるために、著者は将来のレビューのために学習メモのブログをいくつか公開し始めようとしました。もちろん、初心者が新しいテクノロジーを学ぶのに役立つのであれば素晴らしいことです。著者は食べ物です。記事内の記録に間違いがある場合は、読者や友人が批判して修正してください。
(ブログの参照ソース コードは、私のホームページのリソースにあります。学習プロセス中に質問がある場合は、コメント エリアでお気軽に質問してください)
I. 概要
1. ハッシュマップを知る
-
HashMap は、キーと値のペア (キーと値) のマッピングを格納するハッシュ テーブルです。
-
HashMap は Map インターフェイスを実装し、key の HashCode 値に従ってデータを保存し、アクセス速度が速く、最大 1 つのレコード キーを null にすることができ、スレッド同期をサポートしません。
-
HashMap は順序付けされていません。つまり、挿入順序は記録されません。
-
HashMap はAbstractMap を継承し、Map、Cloneable、およびjava.io.Serializableインターフェイスを実装します。
- HashMap のキーと値の型は同じでも異なっていてもよく、文字列 (String) 型のキーと値、または整数 (Integer) のキーと文字列 (String) 型の値にすることができます。
2. HashMapの役割と重要性
HashMap はJava で最も一般的に使用されるデータ構造の 1 つで、Map インターフェイスを実装し、キーと値のペアの保存および取得機能を提供します。HashMap の役割と重要性は、次の側面に反映されています。
- ストレージと取得: HashMap は、大量のキーと値のペアのデータを保存し、キーを通じて対応する値を迅速に取得できます。ハッシュ アルゴリズムを使用してキーを配列の位置にマップし、効率的な検索操作を可能にします。これにより、HashMap は大量のデータを処理するときに要素を迅速に挿入、取得、削除できます。
- 効率的なパフォーマンス: HashMap の内部実装ではハッシュ アルゴリズムが使用されるため、検索操作の平均時間計算量は O(1) (一定時間) です。これは、HashMap がほとんどの場合、非常に効率的な方法で挿入および検索操作を実行できることを意味し、大規模なデータの処理に最適です。
- 柔軟性: HashMap のキーと値は、任意のタイプのオブジェクトにすることができます。これにより、特定のデータ型に限定されることなく、特定のニーズに応じてさまざまな型のデータを HashMap に保存できるようになります。
- 一意のキー: HashMap ではキーの一意性が必要です。つまり、各キーは HashMap 内に 1 回しか出現できません。これは、キーを使用して値を検索するシナリオで非常に役立ちます。たとえば、ユーザー情報を保存する場合、ユーザー ID をキーとして使用して、ユーザーの情報をすばやく取得できます。
- スケーラビリティ: HashMap は動的に拡張でき、保存されるデータの増加に応じて容量を自動的に調整するため、手動による容量管理の煩雑な操作を回避できます。
3. HashMap の基本原理と実装を簡単に説明する
HashMap を使用してデータを保存すると、key のハッシュ値に従って、キーと値のペアが内部配列にマップされます。基本原則は次の手順に要約できます。
1. ハッシュマップ関数
-
ハッシュ関数:ハッシュテーブルの要素はハッシュ関数によって決定され、データ要素のキーワードKeyを引数として、ある関数関係によって計算された値(ハッシュ関数といいます)が要素の格納アドレスとなります。ハッシュ テーブル内のハッシュ関数の設計は非常に重要であり、ハッシュ テーブルを構築するプロセスにおける重要な問題の 1 つでもあります。
-
ハッシュ関数の計算: キーと値のペアを HashMap に挿入すると、HashMap はキーの hashCode() メソッドを呼び出してそのハッシュ値を計算します。ハッシュ値は、キーを配列のインデックス位置にマップするために使用される整数です。
-
ハッシュ値の変換:ハッシュ値が配列のインデックスとして適切であることを確認するために、HashMap は計算されたハッシュ値に対していくつかの変換操作を実行します。一般的な変換方法は、ハッシュ値と配列の長さを使用してモジュロ演算を実行し、配列の範囲内のインデックス値を取得することです。
2. ハッシュマップのストレージ
-
配列ストレージ: HashMap は内部的に配列を維持し、各配列要素はバケットに対応します。各バケットには 1 つ以上のキーと値のペアを保存できます。要素を挿入または検索するとき、HashMap は計算されたインデックス値に従って対応するバケットを見つけ、バケット内で対応する操作を実行します。
-
動的拡張: HashMap のパフォーマンスを向上させるために、保存されているキーと値のペアの数が特定のしきい値に達すると、HashMap はその容量を自動的に拡張します。スケーリング プロセスには、キー ハッシュの再計算と、キーと値のペアのより大きな配列への再配布が含まれます。これによりハッシュの衝突が軽減され、運用効率が向上します。
3. HashMap の競合処理
-
衝突処理: 異なるキーが同じハッシュ値を持つ可能性があるため、衝突が発生します。競合が発生すると、HashMap はリンク リストや赤黒ツリーなどのデータ構造を使用して、同じハッシュ値を持つキーと値のペアを保存します。これらのデータ構造により、複数のキーと値のペアを競合する場所に保存し、キーの equals() メソッドを比較することでそれらを区別することができます。
-
リンク リスト: JDK 8 より前では、HashMap は競合を解決するためにリンク リストを使用していました。複数のキーと値のペアが同じバケットにマッピングされると、リンクされたリストが形成されます。リンクされたリストを走査して、キーと値のペアを検索、挿入、または削除します。ただし、リンクリストの長さが長すぎると、HashMapのパフォーマンスに影響します。
-
赤黒ツリー: JDK 8以降、リンク リストの長さがしきい値 (デフォルトでは 8) を超えると、リンク リストは操作効率を向上させるために自動的に赤黒ツリーに変換されます。赤黒ツリーの検索、挿入、および削除操作は時間の複雑さが低く、平均的な場合には対数の時間の複雑さを維持できます。
- Entry オブジェクト: HashMap は、Entry オブジェクトを使用してキーと値のペアを表します。各Entry オブジェクトには、キー、値、および次の Entry への参照 (リンク リストまたは赤黒ツリー構造を形成する) が含まれています。JDK 8 より前では、高速削除操作をサポートするために、各エントリ オブジェクトには前のエントリへの参照も含まれていました。
一般に、HashMap はハッシュ関数を通じてキーのハッシュ値を計算し、キーと値のペアを内部配列のバケットにマップします。リンク リストや赤黒ツリーなどのデータ構造を使用してハッシュの競合を解決し、動的な拡張を通じてパフォーマンスを向上させます。この実装により、HashMap は一定時間の計算量で挿入、検索、および削除の操作を実行できるようになります。
2. HashMapの作成と共通の操作方法を理解する
1. HashMapの作成
1. パッケージング クラスについて
HashMap の要素は実際にはオブジェクトです. いくつかの一般的な基本型はそのパッケージング クラスを使用できます. 基本型に対応するパッケージング クラスは次のとおりです:
基本タイプ | 参照型 |
---|---|
ブール値 | ブール値 |
バイト | バイト |
短い | 短い |
整数 | 整数 |
長さ | 長さ |
浮く | 浮く |
ダブル | ダブル |
文字 | キャラクター |
2. HashMap は基本型ではなくラッパー型を使用する必要があります
-
一般的な制限: HashMap は、任意の型のキーと値を格納できる汎用クラスです。ただし、ジェネリック型パラメーターはクラスのみにすることができ、プリミティブ型にすることはできません。したがって、プリミティブ型を HashMap のキーまたは値として保存したい場合は、それらを Integer、Double、Boolean などの対応するラッパー型にラップする必要があります。
-
Null 値の処理:基本型を null にすることはできませんが、ラッピング型は null にすることができます。HashMap では、キーと値の両方を null にすることができます。基本型の場合、HashMap に null 値を格納する必要がある場合は、対応するラッパー型を使用する必要があります。
3. HashMapの作成例
- HashMap クラスは java.util パッケージにあり、使用する前に導入する必要があります。構文は次のとおりです。
import java.util.HashMap; // 引入 HashMap 类
- 次の例では、HashMap オブジェクト Sites、整数 (Integer) キー、および文字列 (String) タイプの値を作成します。
HashMap<Integer, String> Sites = new HashMap<Integer, String>();
2. put()要素を追加します。
- HashMap に要素を追加するには、 put()メソッドを使用できます。put() メソッドは 2 つのパラメータを受け入れます。最初のパラメータはキー (Key) で、2 番目のパラメータは値 (Value) です。以下は、HashMap に要素を追加する例です。
map.put("A", 1);
map.put("B", 2);
map.put("C", 3);
- HashMap ではキーと値として null が許可されることに注意してください。HashMap に null をキーとして追加しようとすると、null キーを持つキーと値のペアは 1 つだけになります。また、HashMap はスレッドセーフではないため、マルチスレッド環境で HashMap を使用する場合は、スレッドセーフな ConcurrentHashMap の使用を検討してください。
3. 要素 get() にアクセスします。
- HashMap 内の要素にアクセスするには、 get()メソッドを使用できます。get() メソッドは1 つのパラメータ、取得するキー (Key) を受け取り、そのキーに関連付けられた値(Value)を返します。
int value1 = map.get("A"); // 访问键为"A"的值
int value2 = map.get("B"); // 访问键为"B"的值
-
指定されたキーが HashMap に存在しない場合、 get() メソッドは null を返すことに注意してください。したがって、 get() メソッドを使用して値を取得する前に、 containsKey()メソッドを使用して、指定されたキーが HashMap に存在するかどうかを確認することをお勧めします。
-
さらに、HashMap は要素にアクセスするための他のメソッドも提供します。たとえば、keySet() メソッドはすべてのキーのコレクションを返すことができ、values() メソッドはすべての値のコレクションを返すことができ、entrySet() メソッドはコレクションを返すことができます。キーと値のペアが含まれます。これらのメソッドを使用すると、HashMap 内のすべてのキーと値のペアを反復処理し、対応する操作を実行できます。
4. 要素の削除remove()
- Remove(Object key)メソッドを使用します。このメソッドはキーをパラメータとして受け取り、対応するキーと値のペアを HashMap から削除します。たとえば、キー「key1」を持つ要素を削除する場合は、次のコードを使用できます。
HashMap<String, String> hashMap = new HashMap<>();
hashMap.remove("key1");
- iterator を使用して要素を走査および削除する: Iterator を使用してHashMapのキーと値のペアを走査し、remove() メソッドを使用して要素を削除できます。このアプローチは、要素を条件付きで削除する必要がある場合に適しています。たとえば、値「value1」を持つすべてのキーと値のペアを削除する場合は、次のコードを使用できます。
HashMap<String, String> hashMap = new HashMap<>();
Iterator<Map.Entry<String, String>> iterator = hashMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, String> entry = iterator.next();
if (entry.getValue().equals("value1")) {
iterator.remove();
}
}
- すべてのキーと値のペア (キーと値) を削除するには、 clearメソッドを使用できます。
hashMap.clear();
5. サイズを計算する size()
- HashMap のサイズ (つまり、キーと値のペアの数) を計算するには、size() メソッドを使用できます。このメソッドは、HashMap 内のキーと値のペアの数を返します。
- 以下は、size() メソッドを使用して HashMap のサイズを計算するサンプル コードです。
int size = hashMap.size();
6. それぞれの HashMap を反復する
-
for-each を使用してHashMap の要素を反復できます
-
キーのみを取得したい場合はkeySet() メソッドを使用し、その後 get(key) を通じて対応する値を取得できます。値のみを取得したい場合は、values()メソッドを使用できます。
// 引入 HashMap 类
import java.util.HashMap;
public class RunoobTest {
public static void main(String[] args) {
// 创建 HashMap 对象 Sites
HashMap<Integer, String> Sites = new HashMap<Integer, String>();
// 添加键值对
Sites.put(1, "Google");
Sites.put(2, "Runoob");
Sites.put(3, "Taobao");
Sites.put(4, "Zhihu");
// 输出 key 和 value
for (Integer i : Sites.keySet()) {
System.out.println("key: " + i + " value: " + Sites.get(i));
}
// 返回所有 value 值
for(String value: Sites.values()) {
// 输出每一个value
System.out.print(value + ", ");
}
}
}
- 上記のコードを実行すると、出力は次のようになります。
キー: 1 値: Google
キー: 2 値: Runoob
キー: 3 値: 淘宝網
キー: 4 値: Zhihu
Google、Runoob、淘宝、Zhihu、
7. 空かどうかを判断する isEmpty()
-
HashMap が空かどうかを判断するには、isEmpty() メソッドを使用できます。このメソッドは、HashMap が空かどうかを示すブール値を返します。
-
以下は、isEmpty() メソッドを使用して HashMap が空かどうかを判断するサンプル コードです。
System.out.println("Is HashMap empty? " + hashMap.isEmpty()
8. 指定されたキーが HashMap に存在するかどうかを確認します containsKey()
-
HashMap に特定のキー (キー) が含まれているかどうかを確認するには、containsKey(Object key)メソッドを使用できます。このメソッドはパラメータとしてキーを受け取り、HashMap にキーが含まれているかどうかを示すブール値を返します。
-
以下は、containsKey(Object key) メソッドを使用して HashMap にキーが含まれているかどうかを判断するサンプル コードです。
System.out.println("Does HashMap contain key 'key2'? " + hashMap.containsKey("key1"));
9. 指定されたキーの対応する値を取得します。キーが見つからない場合は、getOrDefault() で設定されたデフォルト値を返します。
-
getOrDefault() メソッドは、指定されたキーの対応する値を取得します。キーが見つからない場合は、デフォルト値セットを返します。
-
getOrDefault() メソッドの構文は次のとおりです。
hashmap.getOrDefault(オブジェクトキー、VdefaultValue)
- パラメータの説明:
1. key - キー
2.defaultValue - 指定されたキーがマッピング関係に存在しない場合、デフォルト値が返されます。
- 戻り値: キーにマップされた値を返します。指定されたキーがマッピング関係で見つからない場合は、指定されたデフォルト値を返します。
import java.util.HashMap;
class Main {
public static void main(String[] args) {
// 创建一个 HashMap
HashMap<Integer, String> sites = new HashMap<>();
// 往 HashMap 添加一些元素
sites.put(1, "Google");
sites.put(2, "Runoob");
sites.put(3, "Taobao");
System.out.println("sites HashMap: " + sites);
// key 的映射存在于 HashMap 中
// Not Found - 如果 HashMap 中没有该 key,则返回默认值
String value1 = sites.getOrDefault(1, "Not Found");
System.out.println("Value for key 1: " + value1);
// key 的映射不存在于 HashMap 中
// Not Found - 如果 HashMap 中没有该 key,则返回默认值
String value2 = sites.getOrDefault(4, "Not Found");
System.out.println("Value for key 4: " + value2);
}
}
- 上記のプログラムを実行すると、出力は次のようになります。
キー 1 の値: Google
キー 4 の値: 見つかりません
要約する
誰でも交換や批評のためにメッセージを残すことができます。記事が役に立った場合、または著者の文章が悪くないと思う場合は、クリックしてフォロー、いいね、ブックマークしてサポートしてください。
(ブログの参照ソース コードは、私のホームページのリソースにあります。学習プロセス中に質問がある場合は、コメント エリアでお気軽に質問してください)