Java 愛好家の皆さん!セットが存在する理由を理解しようとしているコーディング初心者でも、もっと学ぶべきことがあるのではないかと考えている百戦錬磨のプログラマーでも、このガイドはあなたのためのものです。ここでは、Java の Set について、その中心的な目的から複雑な仕組みまで、すべてを詳しく掘り下げていきます。バックルを締めてください!
まず最初に: Set とは何ですか? なぜ気にする必要があるのでしょうか?基本的に、Set は重複した要素を含めることができないコレクションです。言い換えれば、セット内のすべてのアイテムは、カスタム ミーム コレクションと同じくらいユニークです。
あなたがパーティーのゲストリストを作成する任務を負っていると想像してください。誰も招待を 2 回受け取らないようにしたいと考えています (恥ずかしいことなので)。 セットを入力してください 。 Set を使用すると、Java はすべての要素が個別であることを自動的に確認します。 独自性が要件となる状況に最適です。
重複は許可されません : Set の最も重要な特徴は、要素の重複を決して許可しないことです。すでに存在する要素を追加しますか? Java は丁寧に断ります (仕事が多い上司とは異なります)。
順序なし (一般的に) : セットは、リストとは異なり、挿入順序を気にしません。独自性が維持される限り、彼らは幸せです。
Null Handling : 一部のセットでは、要素として null を許可しますが、それは 1 回だけです。
Set が何をするのかがわかったので、Java が提供する Set の種類を見てみましょう:
特性 : HashMap を利用した HashSet は、要素の存在を迅速かつ効率的にチェックします (ほとんどの操作で O(1) 時間の計算量)。
メモリ レイアウト : 内部では ハッシュ テーブル を使用し、要素はハッシュ関数に基づいて保存されます。
NULL は許可されますか? : はい、ただし 1 つだけです。
コード例 :
Set<String> hashSet = new HashSet<>(); hashSet.add("Apple"); hashSet.add("Banana"); hashSet.add("Apple"); // This will be ignored System.out.println(hashSet); // Output: [Apple, Banana]
特性 : HashSet と LinkedList のハイブリッドです。
: 順序を維持するためにハッシュテーブルと二重リンクリストを使用します。
:
Set<String> hashSet = new HashSet<>(); hashSet.add("Apple"); hashSet.add("Banana"); hashSet.add("Apple"); // This will be ignored System.out.println(hashSet); // Output: [Apple, Banana]
特性 : NavigableSet を実装し、ストレージに Red-Black Tree を使用します。
メモリレイアウト : バランスの取れたツリー構造。
コード例 :
Set<String> linkedHashSet = new LinkedHashSet<>(); linkedHashSet.add("Apple"); linkedHashSet.add("Banana"); linkedHashSet.add("Orange"); System.out.println(linkedHashSet); // Output: [Apple, Banana, Orange]
ハッシュ テーブル を使用し、各要素にはハッシュ コードに基づいてバケットが割り当てられます。要素を追加すると、次のことが起こります:
ハッシュ コード計算 : Java は hashCode() メソッドを呼び出して要素のハッシュ コードを取得します。
バケットの決定 : ハッシュ コードはバケット (配列インデックス) にマッピングされます。
衝突処理 : バケットがすでに占有されている (衝突) 場合、Java は チェーン (新しい Java バージョンではリンク リストまたはバランス ツリー) を使用して、バケット内の複数の要素を管理します。同じバケットです。
HashSet 構造の図:
Set<Integer> treeSet = new TreeSet<>(); treeSet.add(42); treeSet.add(10); treeSet.add(25); System.out.println(treeSet); // Output: [10, 25, 42]
[0] -> [Apple] -> [Banana] [1] -> [Grapes] [2] -> [null] [3] -> [Orange] ...
Set<Integer> set1 = new HashSet<>(Arrays.asList(1, 2, 3)); Set<Integer> set2 = new HashSet<>(Arrays.asList(3, 4, 5)); set1.addAll(set2); System.out.println(set1); // Output: [1, 2, 3, 4, 5]
Set<Integer> set1 = new HashSet<>(Arrays.asList(1, 2, 3)); Set<Integer> set2 = new HashSet<>(Arrays.asList(3, 4, 5)); set1.retainAll(set2); System.out.println(set1); // Output: [3]
一般的なシナリオ :
一意のユーザー名を確保します。
アクセスしたページ を追跡します。
アイテムの固有のコレクション (選挙における固有の投票者など) を維持します。
考慮すべき危険信号 :
Set は友達ではありません。代わりにリストを使用してください。
add(E e) : 要素がまだ存在しない場合は追加します。
remove(Object o) : 指定された要素が存在する場合はそれを削除します。
contains(Object o) : 要素が Set 内にあるかどうかを確認します。
size() : 要素の数を返します。
clear() : すべての要素を削除します。
isEmpty() : Set が空かどうかを確認します。
iterator() : 要素の反復子を返します。
Set<String> hashSet = new HashSet<>(); hashSet.add("Apple"); hashSet.add("Banana"); hashSet.add("Apple"); // This will be ignored System.out.println(hashSet); // Output: [Apple, Banana]
同時セット :
スレッドセーフな操作には ConcurrentHashMap.newKeySet() または CopyOnWriteArraySet を使用します。
不変セット :
読み取り専用 Set を作成するには、Collections.unmodifiableSet() または Set.of() を使用します。
Set<String> linkedHashSet = new LinkedHashSet<>(); linkedHashSet.add("Apple"); linkedHashSet.add("Banana"); linkedHashSet.add("Orange"); System.out.println(linkedHashSet); // Output: [Apple, Banana, Orange]
HashSet は、要素の追加、削除、チェックの O(1) パフォーマンスにより、ほとんどのタスクに最適です。 TreeSet はコストが高くなります (O(log n)) が、自然な順序付けという利点が追加されます。 LinkedHashSet は、わずかなオーバーヘッドで予測可能な反復順序を提供します。
問題の種類を認識する :
一意性チェック (文書内の一意の単語の検索など)。
操作の設定 (例: ユーザー間の共通の友人の検索)。
重複のない高速検索 (例: 一定時間内の要素の存在のチェック)。
セットはリストほど魅力的ではなく、マップほど謎めいていないかもしれませんが、一意のコレクションを効率的に維持する上で重要な役割を果たします。これらは、データをクリーンで明確に保ち、予期せぬ結果につながる可能性のある厄介な重複からユーザーを保護する縁の下の力持ちです。アルゴリズムを最適化している場合でも、データの整合性を確保している場合でも、単に に適した構造を選択しようとしている場合でも、動作するだけです。セットを徹底的に理解することで、より強力な開発者になれます。強力なセットの真の可能性を解き放ったと確信して、自信を持ってコーディングに取り組んでください!
これで終わりです!
以上がJava のセットに関する究極のガイド: この素朴なデータ構造のすべての秘密を明らかにするの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。