HashSetC#HashSetデータ構造は、.NET Framework 3.5で導入されました。実装されたメンバの完全なリストは HashSet MSDN ページにあります。
HashSet
name__はオブジェクトの集合を保持しますが、オブジェクトがすでにその集合に含まれているかどうかを簡単かつ迅速に判断できるようにします。これは、配列を内部的に管理し、オブジェクトのハッシュコードから計算されたインデックスを使用してオブジェクトを格納することによって行われます。 ここで見てください
HashSet
name__は、一意の要素を含む番号なしコレクションです。標準のコレクション操作Add、Remove、Containsがありますが、ハッシュベースの実装を使用しているため、これらの操作はO(1)です。 (例えばListはContainsとRemoveのO(n)とは対照的に。)HashSet
name__はunion、intersectionのような標準の集合演算も提供します。、および対称差. ここを見てください
Setにはさまざまな実装があります。要素をハッシュすることで挿入や検索の操作を超高速にするものもあります。ただし、それは要素が追加された順序が失われることを意味します。他の実装では、実行時間が遅くなるという犠牲を払って追加された順序を保持します。
C#のHashSet
name__クラスは最初のアプローチを採用しているため、要素の順序は保持されません。通常のList
name__よりはるかに高速です。いくつかの基本的なベンチマークは、HashSetが基本型(int、double、boolなど)を扱うときにかなり速いことを示しました。クラスオブジェクトを扱うときはずっと速いです。つまり、HashSetは速いということです。
HashSet
name__の唯一のキャッチは、インデックスによるアクセスがないことです。要素にアクセスするには、列挙子を使うか、組み込み関数を使ってHashSet
name__をList
name__に変換し、それを繰り返すことができます。 ここで見てください
HashSet
は内部構造(ハッシュ)を持ち、そこでアイテムをすばやく検索して識別できます。欠点は、HashSet
の繰り返し(またはインデックスによる項目の取得)はかなり遅いということです。
では、なぜエントリがセットに既に存在するかどうかを知りたいと思う人がいるでしょうか。
HashSet
が役に立つ状況の1つは、重複が存在する可能性があるリストから個別の値を取得することです。アイテムがHashSet
に追加されると、そのアイテムが存在するかどうかをすばやく判断できます(Contains
演算子)。
HashSet
の他の利点は、Set操作です。IntersectWith
、IsSubsetOf
、IsSupersetOf
、Overlaps
、SymmetricExceptWith
、UnionWith
。
オブジェクト制約言語 に慣れている場合は、これらの集合演算を確認してください。また、それが実行可能UMLの実装に一歩近づくこともわかります。
簡単に言って、台所の秘密を明かすことなく:一般的なセットは、重複する要素を含まず、要素が特定の順序で並んでいないコレクションです。そのため、A HashSet<T>
は一般的なList<T>
に似ていますが、順序を失うことを犠牲にして(名前が示すようにハッシュテーブルを介して)高速検索に最適化されています。
アプリケーションの観点からは、重複を避けるためだけに必要な場合は、検索、挿入、削除 の複雑さがO(1) - 定数 であるためHashSet
が探しています。 。つまり、HashSet
がそのような要素が存在するかどうかを確認するのに同じ時間がかかることに加えて、O(1)に要素を挿入しているのでこれも完璧です。一種のこと。