web-dev-qa-db-ja.com

C#セットコレクション?

誰かがC#にJavaのSetコレクションに相当するものがあるかどうか知っていますか?値を入力して無視することでDictionaryまたはHashTableを使用してセットを多少模倣できることを私は知っていますが、それは非常に洗練された方法ではありません。

445
Omar Kooheji

HashSet を試してください。

HashSet(Of T)クラスは、高性能な集合演算を提供します。集合は、重複する要素を含まず、要素の順序が特定の順序になっていないコレクションです。

HashSet(Of T)オブジェクトの容量は、そのオブジェクトが保持できる要素数です。 HashSet(Of T)オブジェクトの容量は、要素がオブジェクトに追加されると自動的に増加します。

HashSet(Of T)クラスは数学セットのモデルに基づいており、 Dictionary(Of TKey、TValue) または ハッシュテーブル のコレクション。簡単に言うと、HashSet(Of T)クラスは、値のない Dictionary(Of TKey、TValue) コレクションと考えることができます。

HashSet(Of T)コレクションは並べ替えられず、重複する要素を含めることはできません...

108
Leahn Novash

.NET 3.5を使用している場合は、 HashSet<T> を使用できます。 Javaがそうであるように.NETがセットを提供しないのは本当です。

Wintellect PowerCollections も役に立ちます。

402
Jon Skeet

HashSet<T>データ構造体:

Framework Class LibraryのHashSet<T>データ構造は、.NET Framework 3.5で導入されました。そのメンバーの完全なリストは、 MSDNリファレンスページのHashSet<T> にあります。

HashSet<T>は、 数学セット を基に多かれ少なかれモデル化されています。

  1. 重複する値が含まれていない可能性があります。

  2. その要素は特定の順序ではありません。したがって、この型は IList<T> インターフェースを実装していませんが、より基本的な ICollection<T> を実装しています。結果として、ハッシュセット内の要素はインデックスを通してランダムにアクセスすることはできません。それらは列挙子を通してのみ繰り返すことができます。

  3. UnionIntersectionIsSubsetOfIsSupersetOfなどの特定の集合関数が使用可能です。複数のセットを扱うときに便利です。

HashSet<T>List<T>のもう1つの違いは、ハッシュセットのAdd(item)メソッドを呼び出すとブール値が返されることです。項目が追加された場合はtrue、それ以外の場合はfalseが返されます。

List<T>ではないのはなぜですか?

HashSet<T>は単なるユニークなオブジェクトの集まりなので、なぜそれがデータ構造でなければならないのか疑問に思うかもしれません。通常のList<T>は、追加する前にリストにオブジェクトが見つかったかどうかをチェックすることで、同じ動作をさせることができます。

簡単な答えはスピードです。通常のList<T>を検索するのは、要素が追加されるにつれて非常に速くなります。 HashSet<T>は高速検索と挿入速度を可能にする構造設計を必要とします。

ベンチマーク:

HashSet<T>List<T>のパフォーマンス速度を比較しましょう。

各試行は、各コレクションに0から9,999までの整数を追加することからなりました。ただし、mod 25が各整数に適用されました。 Mod 25では、項目25の種類が最大になります。10,000個の要素が追加されたため、これにより400回の衝突が発生し、データ構造に検索アルゴリズムを使用する機会が与えられました。 10,000回の試行後に時間を3回測定し、平均した。

テストの実行時間は私のハードウェアに依存しているのであまり多くの注意を払ってはいけませんが、それらが互いにどのように比較されるかを見てください。

           Average time [ms]
----------------------------
HashSet<T>             2,290
List<T>                5,505

それでは、プリミティブ型の代わりに要素オブジェクトを作りましょう。 PersonName、およびLastNameの3つのフィールドを持つ簡単なIDクラスを書きました。オブジェクトを比較するための具体的な方法を含めなかったので、すべての要素が衝突することなく追加されます。今回は、1回の試行で1,000個のPersonオブジェクトが各コレクションに追加されました。 3セットの1,000試行の合計時間が平均された。

           Average time [ms]
----------------------------
HashSet<Person>          201
List<Person>           3,000

ご覧のとおり、オブジェクトを使用すると実行時間の差が天文学的になり、HashSet<T>が有利になります。

115

.NET 4.0以降を使用している場合:

ソートが必要な場合は、 SortedSet<T> を使用してください。そうでない場合は、 HashSet<T> を使用してください。検索や操作のためにO(1)が使用されるためです。 SortedSet<T>は検索や操作のためのO(log n)です。

18
Derek W

私はIesi.Collectionsを使用しています http://www.codeproject.com/KB/recipes/sets.aspx

それは多くのOSSプロジェクトで使われています、私は最初にNHibernateでそれに出会いました

14
Chris Canal

値にnullを格納して、Dictionary<T, object>の周りにラッパーを使用します。これはO(1)を追加、検索、削除することを可能にし、すべての目的や目的に対して集合のように振る舞います。

12
thecoop

CodePlexで PowerCollections をご覧ください。 SetやOrderedSetとは別に、Deque、MultiDictionary、Bag、OrderedBag、OrderedDictionary、OrderedMultiDictionaryなどの便利なコレクション型がいくつかあります。

より多くのコレクションについては、 C5 Generic Collection Library もあります。

11
dpan

あなたは数時間であなた自身の実行可能なセットの実装を実装することができます。私がそれをしなければならなかったとき、私はこれを使いました(すみません、私は便利なコードを持っていません): http://Java.Sun.com/j2se/1.4.2/docs/api /Java/util/Set.html

0
cciotti