されることがあります。は、HashSet<T> type?
-
12-09-2019 - |
質問
私の HashSet<T>
タイプがわかりませんがコレクション.
することができるで置き換え List<T>
?その性能 HashSet<T>
するより良いものの、見えない個人のアクセスを
このための列挙?
解決
HashSet<T>
について重要なことは、名前に権利がある:それは、のの設定です。あなたは、単一のセットで行うことができる唯一のものは、そのメンバーが何であるかを確立すること、およびアイテムがメンバーであるかどうかを確認することです。
(例えばset[45]
)セットの概念を誤解されて尋ねます。セットの第45回要素のようなものはありません。セット内のアイテムには順序がありません。セット{1、2、3}と{2、3、1}、それらが同じメンバーシップを有し、会員はそれが重要なすべてであるため、あらゆる点で同一です。
これはやってはそうセット内の項目の順序を課しているためHashSet<T>
を反復処理するためにやや危険です。そのためには、実際にセットのプロパティではありません。あなたはそれに頼るべきではありません。コレクション内の項目の順序が重要な場合は、そのコレクションはセットではありません。
セットは本当に限られており、ユニークなメンバーです。一方、彼らは本当に速いです。
他のヒント
この例の場を使ってい HashSet<string>
:
の構文ハイライタのためのUnrealScriptファイルで新たな機能 ハイライトDoxygen-スタイルのコメント.いかどうかを知ることができる場合 @
または \
コマンドが有効かどうかを示すグレーの(有効)または赤(無効).してい HashSet<string>
すべての有効なコマンドだっ @xxx
トークンはレクサーに使っている validCommands.Contains(tokenText)
私はO(1)有効性チェック。私はどんなものを除く 存在 のコマンド セット の有効なっています。きの代わっていないとき:
Dictionary<string, ?>
:どのような使用のための価値とは?この値は無意味でだけ使用ContainsKey
.注意:ます。純3.0この時はO(1)ルックアップ-HashSet<T>
追加され3.0拡張を実施ISet<T>
のための4.0の製品をご用意しています。List<string>
:がんのリストから選別、使用できますBinarySearch
, でO(log n)(なかったことをいう。しかし、マイリストの有効なコマンドは固定リストに変わることはありません、このいたしませんより適切だったの...string[]
:再度、Array.BinarySearch
すO(log n)。場合のリストは、この最も良好なパフォーマンスを示します。で常に少ないスペースのオーバーヘッドによHashSet
,Dictionary
, やList
.でもBinarySearch
, な高速化のための大きなセットが、小さなセットでも価値があると実験.鉱山は、数百項目にもなっていたので抜いてしまいました。
HashSet<T>
はICollection<T>
インタフェースを実装します:
public interface ICollection<T> : IEnumerable<T>, IEnumerable
{
// Methods
void Add(T item);
void Clear();
bool Contains(T item);
void CopyTo(T[] array, int arrayIndex);
bool Remove(T item);
// Properties
int Count { get; }
bool IsReadOnly { get; }
}
List<T>
を拡張 IList<T>
が実装ICollection<T>
、
public interface IList<T> : ICollection<T>
{
// Methods
int IndexOf(T item);
void Insert(int index, T item);
void RemoveAt(int index);
// Properties
T this[int index] { get; set; }
}
A HashSetのは、意味論を設定し、内部でハッシュテーブルを経由して実装されています:
それは、インデックス/位置/リストの挙動を失った場合、のセットはありませんが含まれているコレクションです 要素を複製し、その要素 順不同である。
、HashSetのゲインを何?
HashSetのからアイテムを追加し、検索(1)操作(一覧はO(1)を追加しているOに近いオブジェクト自体によってではなく、インデクサを介して常に、そして、O(1)(、インデックスによってOを取得しますn))を削除/見つけます。
A HashSetのの挙動のみ値自体/加算値としてキーを除去し、辞書を無視しDictionary<TKey,TValue>
を使用して比較することができます。あなたが重複した値を持っていない辞書のキーを期待し、それは、「設定」の部分のポイントです。
パフォーマンスは、リスト上のHashSetを選択する悪い理由だろう。代わりに、あなたの目的は、より良いものをキャプチャ?順序が重要な場合は、[設定(またはHashSetの)が出ています。重複も同様に、許可されている場合。しかし、そこに私たちが順番を気にしない、と私たちはかなり重複していないだろうときの状況がたくさんある - そしてあなたが設定したいときです。
。HashSetのは、ののハッシュすることによって実現して設定されます。セットが重複要素を含まない値の集合です。セット内の値は、典型的には、順不同です。だから、いいえ、セットは(あなたが最初の場所にセットを使用する必要がありました場合を除く)リストを置き換えるために使用することはできません。
あなたはセットがために良いかもしれないかと思っている場合:どこでもあなたが明らかに、重複を取り除きたいです。やや不自然な例として、あなたがソフトウェアプロジェクトの10.000リビジョンのリストを持っているとしましょう、あなたは多くの人々がそのプロジェクトにどのように貢献したかを知りたいです。あなたはSet<string>
を使用し、リビジョンのリストを反復処理し、セットに各リビジョンの作成者を追加することができます。あなたが反復完了したら、セットのサイズは、あなたが探していた答えはあります。
HashSetのはIEnumerbleコレクション内の重複要素を削除するために使用されるだろう。たとえば、
List<string> duplicatedEnumrableStrings = new List<string> {"abc", "ghjr", "abc", "abc", "yre", "obm", "ghir", "qwrt", "abc", "vyeu"};
HashSet<string> uniqueStrings = new HashSet(duplicatedEnumrableStrings);
これらのコードが実行された後に、、uniqueStringsは、{ "vyeu"、 "ABC"、 "ghjr"、 "YRE"、 "OBM"、 "qwrt" を}保持;
おそらくhashsetsの最も一般的な使用は、それらが特定の要素を含むかどうかを確認することで、彼らのためにO(1)操作に近くなる含めるためにチェック対象のリストとは対照的に、(十分に強力なハッシュ関数を仮定して) O(N)である(そしてそれはO(Nログ)されたセットをソート)。あなたがチェックの多くを行うのであれば、アイテムがいくつかのリストに含まれているかどうか、hahssetsは、パフォーマンスの向上であるかもしれません。あなただけの今までにそれらを反復した場合、大きな違いがありません(セット全体の繰り返し処理は、O(n)は、項目を追加する際にリストとhashsetsと同じで多少のオーバーヘッドを持っている)。
そして、いや、できないインデックスのセットを注文されていないので、とにかく意味をなさないセット。あなたには、いくつかの項目を追加した場合、セットが最初にあった1覚えて、どの第二などはありません。
List<T>
は情報の順序付きセットを格納するために使用されます。あなたは、リストの要素の相対順序がわかっている場合は、一定の時間内にそれらにアクセスすることができます。しかし、要素がリストにある場所を決定するか、リストに存在するかどうかをチェックするために、検索時間が直線的です。一方、HashedSet<T>
は、格納されたデータの順序を保証しません、その結果、その要素に対して一定のアクセス時間を提供します。
、HashedSet<T>
は集合セマンティクスを実装するデータ構造であるの。データ構造は、伝統的なリストの実装と同様に効率的に行うことができない一連の操作(すなわちユニオン、差、交差)を実装するために最適化されます。
だから、本当に使用するデータの種類を選択することはあなたがあなたのアプリケーションをどうしようとしているかに依存します。あなたの要素がコレクションに命じているかを気にし、唯一enumarateまたは存在をチェックしたくない場合は、HashSet<T>
を使用しています。それ以外の場合は、List<T>
または他の適切なデータ構造を使用することを検討します。
HashSet<T>
はhref="http://en.wikipedia.org/wiki/Set_(mathematics)" rel="nofollow noreferrer">数学を設定します。この場合には、設定された要素の等価性を比較するためにハッシュコード(各項目のGetHashCode
結果)を使用します。
のセットリストとは異なります。あなたは第二の同一の要素を追加しようとHashSet<T>
だけfalse
を返します。内部データ構造が単純にハッシュテーブルであるため、実際に、要素のルックアップは、(O(1)
時間)非常に速いです。
あなたはそれが潜在的にあなたのコレクションに望ましくない重複したアイテムを持っている問題を許すかもしれませんが、List<T>
がappropiateあるHashSet<T>
を使用して最大の過ちではないことに注意し、使用する迷っている場合。代わりにO(1)
時間の(完璧なバケットのための)理想的O(n)
- - 詳細は何ですか、検索(項目検索は)非常に効率的です。多くのシナリオでは非常に重要です。
要するに - あなたは、あなたが(Sに相当TにIEquatableを実装するか、HashSetの+)HashSetのを考慮する必要があります辞書(またはSがTの財産である辞書)を使用するように誘惑され、いつでも
基本的シナリオ HashSet<T>
使いたい場合、具体的な設定の操作を二回収によLINQを提供します。LINQの他の方法 Distinct
, Union
, Intersect
や Except
ほどほとんどの状況もうけられることがあります詳細粒業務 HashSet<T>
提供:
UnionWith
IntersectWith
ExceptWith
SymmetricExceptWith
Overlaps
IsSubsetOf
IsProperSubsetOf
IsSupersetOf
IsProperSubsetOf
SetEquals
もう一つの違いとLINQ、 HashSet<T>
"重複する"方法はLINQストを返新 IEnumerable<T>
, は、 HashSet<T>
方法を変更する源です。