マップ。これらには、隠された宝があったり、金を探す際に「X」マークが付いていたりするわけではないかもしれませんが、Java 開発における宝の山です。あなたが新人の開発者であっても、コーヒーで汚れたキーボードを使用する熟練のアーキテクトであっても、マップを理解することでコーディング作業が向上します。 Java のマップを隅々まで巡る壮大な旅に出かけましょう。
簡単に言えば、マップ はキーと値のペアを格納するデータ構造です。これを現実世界の辞書のように考えてください。単語 (キー) とその意味 (値) があります。マップ内のすべてのキーは一意である必要がありますが、値は重複する可能性があります。
キャッシュ : 計算の繰り返しを避けるために結果を保存します。
データベースのインデックス作成 : 主キーを使用してデータに素早くアクセスします。
構成 : 設定と環境設定をキーと値のペアとして保存します。
頻度のカウント : 要素の出現回数をカウントします (単語の頻度など)。
マップは、素早い検索、挿入、更新が必要なシナリオで威力を発揮します。これらは、一意の識別子 (キー) が特定のエンティティ (値) に関連付けられる関係をモデル化するために使用されます。
Java は、さまざまなニーズに合わせてさまざまなマップを提供します。
3.1 ハッシュマップ
実装 : ハッシュ テーブル を使用します。
パフォーマンス : O(1) 取得および書き込み操作の平均時間。
特性 : 順序付けされておらず、1 つの null キーと複数の null 値が許可されます。
メモリ レイアウト : キーはバケットの配列に保存されます。各バケットはリンクされたリストまたはツリーです (衝突がしきい値を超えた場合)。
3.2 LinkedHashMap
実装 : 挿入順序 を維持するために、リンクされたリストを使用して HashMap を拡張します。
ユースケース : エントリの順序を保持する必要がある場合 (LRU キャッシュなど)。
パフォーマンス : リンク リストのオーバーヘッドのため、HashMap よりわずかに低くなります。
3.3 ツリーマップ
実装 : 赤黒ツリー (平衡二分探索ツリーの一種) を使用します。
パフォーマンス : 取得、配置、および削除操作の O(log n)。
特性 : キーの自然な順序またはカスタム コンパレータに従って並べ替えられます。 3.4 ハッシュテーブル
古代の歴史の警告 : Java の初期の時代の名残で、同期されておりスレッドセーフですが、パフォーマンスに大きなペナルティが伴います。
特性 : null キーまたは値は許可されません。
3.5 同時ハッシュマップ
スレッドセーフ ヒーロー : マップ全体をロックせずに同時アクセスできるように設計されています。
実装 : セグメントベースのロック機構を使用します。
パフォーマンス : 同時読み取り/書き込みアクセス下で高いスループットを提供します。
ハッシュ : キーがハッシュ関数に渡され、配列 (バケット) 内のインデックスが返されます。
衝突解決 : 複数のキーが同じハッシュ インデックスを生成する場合:
int hash = key.hashCode() ^ (key.hashCode() >>> 16); int index = hash & (n - 1); // n is the size of the array (usually a power of 2)
赤黒ツリー : 自己バランス型ツリーにより、根から葉までの最長経路が最短経路の 2 倍以下になることが保証されます。
順序 : キーを自然な順序またはコンパレータに基づいて自動的に並べ替えます。
4.3 同時ハッシュマップの仕組み
バケット ロック : 個別のセグメントに対してきめ細かいロックを使用して同時実行性を向上させます。
メモリ効率 : 配列とリンクされたノードの組み合わせを利用します。
5.1 put(Kキー、V値)
キーと値のペアを挿入または更新します。
Map<String, Integer> map = new HashMap<>(); map.put("Alice", 30); map.put("Bob", 25);
キーに関連付けられた値を取得します。
int age = map.get("Alice"); // 30
マップに特定のキーが含まれているかどうかを確認します。
boolean exists = map.containsKey("Bob"); // true
特定のキーのマッピングを削除します。
map.remove("Bob");
エントリ、キー、または値を反復処理します。
for (Map.Entry<String, Integer> entry : map.entrySet()) { System.out.println(entry.getKey() + " = " + entry.getValue()); }
HashMap はバケット (配列) を中心に構造化されています。各バケットは次のいずれかを指します:
Java 8 より前 : リンクされたリスト。
Java 8 : バケット内の要素の数がしきい値を超えるとツリーに変換されます。
視覚的表現 :
int hash = key.hashCode() ^ (key.hashCode() >>> 16); int index = hash & (n - 1); // n is the size of the array (usually a power of 2)
単語頻度カウンターや文字列内の文字数などのアルゴリズムで一般的に使用されます。
Map<String, Integer> map = new HashMap<>(); map.put("Alice", 30); map.put("Bob", 25);
int age = map.get("Alice"); // 30
マップを使用する場合 :
検索の多いタスク : O(1) の時間計算量が必要な場合。
数と頻度の問題 : 競技プログラミングでは一般的です。
キャッシュとメモ化 : マップを使用して、動的プログラミングの結果をキャッシュできます。
整数の配列を指定すると、特定のターゲットを合計する 2 つの数値のインデックスを返します。
boolean exists = map.containsKey("Bob"); // true
整数をキーとして使用する場合、Java は -128 から 127 までの整数をキャッシュすることに注意してください。その範囲を超えると、キーが異なる方法でボックス化される可能性があり、非効率につながる可能性があります。
パフォーマンスを調整するには、hashCode() を慎重にオーバーライドしてください。
map.remove("Bob");
可変オブジェクトをキーとして使用することは 悪い習慣です。キーオブジェクトが変更されると、取得できなくなる可能性があります。
キーと値の関係 : 問題に、ある項目が別の項目にマップされる関係がある場合。
重複カウント : 繰り返される要素を検出します。
高速データ取得 : O(1) ルックアップが必要な場合。
マップは、Java で最も多用途かつ強力なデータ構造の 1 つです。汎用用途の HashMap、並べ替えデータ用の TreeMap、同時実行用の ConcurrentHashMap のいずれであっても、どれを使用し、どのように動作するかを知ることは、より適切で効率的なコードを作成するのに役立ちます。
したがって、次回誰かがマップについて尋ねてきたら、笑顔でコーヒーを飲みながら、「どこから始めればいいですか?」と言えます
以上がJava マップの詳細: すべての開発者のための究極のガイドの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。