HashSetの違いは何ですか<T> とリスト<T>?
-
29-10-2019 - |
質問
あなたは違いが何であるかを説明できますか HashSet<T>
と List<T>
NETで?
たぶん、あなたはどのような場合に例で説明することができますか HashSet<T>
に対して好まれるべきです List<T>
?
解決
リストとは異なり<> ...
-
HashSetは、重複するメンバーがないリストです。
-
HashSetは一意のエントリのみを含むように制約されているため、内部構造は検索用に最適化されています(リストと比較して)-かなり高速です
-
HashSetに追加すると、ブール値が返されます。Setに既に存在するために追加が失敗した場合は、falseになります。
-
セットに対して数学的なセット操作を実行できます:Union / Intersection / IsSubsetOfなど。
-
HashSetはIListのみを実装していませんICollection
-
HashSetでインデックスを使用することはできず、列挙子のみを使用できます。
HashSetを使用する主な理由は、Set操作の実行に関心がある場合です。
与えられた2つのセット:hashSet1とhashSet2 ジェネラコディセタグプレ
は、LINQを使用した同等の操作と比較して飛行します。書くのもいいです!
他のヒント
HashSet<T>
は、包含のためのO(1)
ルックアップを提供するように設計されたクラスです(つまり、このコレクションには特定のオブジェクトが含まれており、答えをすばやく教えてくれます)。
List<T>
は、動的に成長できる(動的配列を考えてください)ジェネラコディセタグコードのランダムアクセスを備えたコレクションを提供するように設計されたクラスです。封じ込めをO(1)
時間でテストできます(リストがソートされていない限り、O(n)
時間でバイナリ検索を実行できます)。
例を挙げて、
O(log n)
よりHashSet<T>
を優先する必要がある場合を説明できるかもしれません
List<T>
の封じ込めをテストする場合。
より正確には、例を使って実証することができます,
次の例のようにHashSetを使用することはできません。
HashSet<string> hashSet1 = new HashSet<string>(){"1","2","3"};
for (int i = 0; i < hashSet1.Count; i++)
Console.WriteLine(hashSet1[i]);
hashSet1[i]
エラーが発生します:
型の式に[]を使用したインデックスを適用できません 'システム。コレクション。一般的な。ハッシュセット'
Foreach文を使用できます:
foreach (var item in hashSet1)
Console.WriteLine(item);
Listではこれを行うことができますが、重複した項目をHashSetに追加することはできません。 hashsetに項目を追加している間、項目が含まれているかどうかを確認できます。
HashSet<string> hashSet1 = new HashSet<string>(){"1","2","3"};
if (hashSet1.Add("1"))
Console.WriteLine("'1' is successfully added to hashSet1!");
else
Console.WriteLine("'1' could not be added to hashSet1, because it contains '1'");
HashSetには次のような便利な関数があります IntersectWith
, UnionWith
, IsProperSubsetOf
, ExceptWith
, SymmetricExceptWith
など。
IsProperSubsetOf
:
HashSet<string> hashSet1 = new HashSet<string>() { "1", "2", "3", "4" };
HashSet<string> hashSet2 = new HashSet<string>() { "2", "4", "6", "8" };
HashSet<string> hashSet3 = new HashSet<string>() { "1", "2", "3", "4", "5" };
if (hashSet1.IsProperSubsetOf(hashSet3))
Console.WriteLine("hashSet3 contains all elements of hashSet1.");
if (!hashSet1.IsProperSubsetOf(hashSet2))
Console.WriteLine("hashSet2 does not contains all elements of hashSet1.");
UnionWith
:
HashSet<string> hashSet1 = new HashSet<string>() { "3", "4" };
HashSet<string> hashSet2 = new HashSet<string>() { "2", "4", "6", "8" };
hashSet1.UnionWith(hashSet2); //hashSet1 -> 3, 2, 4, 6, 8
IntersectWith
:
HashSet<string> hashSet1 = new HashSet<string>() { "3", "4", "8" };
HashSet<string> hashSet2 = new HashSet<string>() { "2", "4", "6", "8" }
hashSet1.IntersectWith(hashSet2);//hashSet1 -> 4, 8
ExceptWith
:
HashSet<string> hashSet1 = new HashSet<string>() { "1", "2", "3", "5", "6" };
HashSet<string> hashSet2 = new HashSet<string>() { "1", "2", "3", "4" };
hashSet1.ExceptWith(hashSet2);//hashSet1 -> 5, 6
SymmetricExceptWith
:
HashSet<string> hashSet1 = new HashSet<string>() { "1", "2", "3", "5", "6" };
HashSet<string> hashSet2 = new HashSet<string>() { "1", "2", "3", "4" };
hashSet1.SymmetricExceptWith(hashSet2);//hashSet1 -> 4, 5, 6
ちなみに、順序はハッシュセットには保存されません。この例では、最後に要素"2"を追加しましたが、それは2番目の順序です:
HashSet<string> hashSet1 = new HashSet<string>() { "3", "4", "8" };
hashSet1.Add("1"); // 3, 4, 8, 1
hashSet1.Remove("4"); // 3, 8, 1
hashSet1.Add("2"); // 3, 2 ,8, 1
次の場合は、List<T>
を使用します。
- アイテムのコレクションを特定の順序で保存します。
(アイテム自体の値ではなく)必要なアイテムのインデックスがわかっている場合、取得は
O(1)
です。インデックスがわからない場合は、アイテムの検索に時間がかかります。並べ替えられていないコレクションのO(n)
です。次の場合は、
Hashset<T>
を使用します。- 特定のオブジェクトがコレクションに含まれているかどうかをすばやく確認します。
検索したいものの名前がわかっている場合、ルックアップは
O(1)
です(これが「ハッシュ」部分です)。List<T>
のように順序が維持されず、重複を保存することはできません(重複を追加しても効果はありません。これが「設定」部分です)。Hashset<T>
を使用する場合の例は、Scrabbleのゲームでプレイされた単語が英語(または他の言語)で有効な単語であるかどうかを確認したい場合です。そのようなゲームのオンラインバージョンのすべてのインスタンスで使用されるWebサービスを構築したい場合はさらに良いでしょう。List<T>
は、プレーヤーのスコアを追跡するためのスコアボードを作成するための優れたデータ構造です。
- 特定のオブジェクトがコレクションに含まれているかどうかをすばやく確認します。
リストは順序付きリストです。
- 整数インデックスからアクセス
- 重複を含めることができます
- 予測可能な順序があります
HashSetはセットです。それ:
- 重複するアイテムをブロックできます( Add(T)を参照)
- セット内のアイテムの順序を保証するものではありません
- セットで期待される操作があります。例:、IntersectWith、IsProperSubsetOf、UnionWith。
リストは、アイテムを追加、挿入、削除できる配列のようにコレクションにアクセスする場合に適しています。コレクションを、順序が重要ではないアイテムの「バッグ」のように扱いたい場合、またはIntersectWithやUnionWithなどの操作を使用して他のセットと比較したい場合は、HashSetが適しています。
リストは必ずしも一意ではありませんが、ハッシュセットは一意です。
リストはタイプTのオブジェクトの順序付けられたコレクションであり、配列とは異なり、エントリを追加および削除できます。
保存した順序でメンバーを参照するリストを使用し、アイテム自体ではなく位置によってメンバーにアクセスします。
HashSetは、アイテム自体がキーであり値でもある辞書のようなものであり、順序は保証されません。
オブジェクトがコレクション内にあることを確認する場所でHashSetを使用します
これらのデータ構造をデータ駆動型開発の実際の使用に適用することにした場合、HashSetは、データクレンジングと移行のためにデータアダプターソースに対するレプリケーションをテストするのに非常に役立ちます。
また、DataAnnotationsクラスを使用する場合、クラスプロパティにKeyロジックを実装し、HashSetを使用してNatural Index(クラスター化されているかどうかに関係なく)を効果的に制御できます。これは、Listの実装では非常に困難です。
リストを使用するための強力なオプションは、DropDownListヘルパーのMVCビューにクラスのリストを送信したり、WebApiを介してJSON構造として送信したりするなど、ビューモデルに複数のメディアのジェネリックを実装することです。このリストにより、一般的なクラス収集ロジックが可能になり、さまざまなメディアに対して単一のビューモデルを計算するためのより「インターフェイス」のようなアプローチの柔軟性が維持されます。