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


488

SetC#にJavaのコレクションに相当するものがあるかどうか誰かが知っていますか?値を入力して無視することで、a Dictionaryまたはa を使用してセットをいくらか模倣できることは知っていますがHashTable、それはあまりエレガントな方法ではありません。

回答:


142

HashSetを試してください:

HashSet(Of T)クラスは、高性能のセット操作を提供します。セットは、重複する要素を含まないコレクションであり、その要素は特定の順序ではありません...

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

HashSet(Of T)クラスは数学セットのモデルに基づいており、Dictionary(Of TKey、TValue)またはHashtableコレクションのキーにアクセスするのと同じような高性能のセット操作を提供します。簡単に言えば、HashSet(Of T)クラスは値のないDictionary(Of TKey、TValue)コレクションと考えることができます。

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


8
残念ながら、HashSetは最近まで追加されていませんでした。フレームワークの古いバージョンで作業している場合は、変更されたDictionary <>またはHashtableを使用する必要があります。
グレッグD

413

.NET 3.5を使用している場合は、を使用できますHashSet<T>。.NETがJavaのようにセットに対応していないのは事実です。

WintellectのPowerCollectionsはあまりにも役立つかもしれません。


16
一部の言語ではSetがキーワードであるため、問題が発生する可能性があります。
Jon Skeet、

3
@マニッシュ:いいえ、違います。C#3仕様のセクション2.4.3を参照してください。プロパティに対して特別な意味を持つだけです。
Jon Skeet、2010

28
SetだけでなくHashSetと呼ぶ理由は、Javaの場合と同じです。「Set」はインターフェースを表しますが、「HashSet」は実装を表します。具体的には、これはHash Mapに基づくSetです。このように、挿入とアクセスにO(1)アクセス時間がかかることと、挿入とアクセスにO(n)時間がかかると予想される "LinkedListSet"がわかっている(または強く期待する)必要があります。
David Souther、

5
「.NETはJavaと同じようにセットに対応していない」とはどういう意味ですか?このセットは、Javaに比べてどういうわけか不完全ですか?
Louis Rhys、2011

34
@ルイ:どのセットについて話しているのですか?Javaには、さまざまな状況に応じてさまざまなSetの実装が用意されています。.NETには、.NET 3.5(HashSet)に1つ、.NET 4(HashSetおよびSortedSet)に2つありました。.NET 3.5が始まるまで待たなければならなかったという事実は、かなり驚くべきことです。
Jon Skeet、2011

26

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

並べ替えが必要な場合は、を使用してくださいSortedSet<T>。そうでない場合は、検索と操作の操作HashSet<T>O(1)ために使用します。一方SortedSet<T>O(log n)、検索用と操作を操作します。



13

の周りにラッパーを使用Dictionary<T, object>して、値にnullを格納します。これにより、O(1)にキーの追加、検索、削除が行われ、すべての意図と目的に対して、セットのように機能します。


2
std :: unordered_setとほぼ同等であることを意味する必要があります。std :: setが順序付けられます。たとえば、範囲の開始点と終了点をすばやく見つけて、キーの順序でアイテムにアクセスし、開始点から終了点まで繰り返すことができます。SortedDictionary std :: set ほぼ同じです。
doug65536 2013

11

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

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


-5

これは古いスレッドであることはわかっていますが、同じ問題が発生していて、同じシードを指定するとGetHashCode()が異なるコードを返すため、HashSetは非常に信頼できないことがわかりました。だから、私は、なぜリストを使用して、このようなaddメソッドを非表示にしないのかと思いました

public class UniqueList<T> : List<T>
{
    public new void Add(T obj)
    {
        if(!Contains(obj))
        {
            base.Add(obj);
        }
    }
}

ListはEqualsメソッドを使用して等しいかどうかを判断するだけなので、T型にEqualsメソッドを定義して、目的の結果を確実に得ることができます。


13
これを使いたくない理由List.Containsは、がO(n)複雑であるため、Addメソッドも複雑になるためですO(n)。インナーコレクションと仮定すると、サイズを変更する必要はありませんAdd両方のためにListHashMapのものでなければならないO(1)複雑。TLDR:これは機能しますが、ハックで効率が落ちます。
Richard Marskell-Drackir 2012年

6
もちろん、オブジェクトがGetHashCodeに適切な値を返さない場合は、それらをハッシュベースのコンテナーに配置しないでください。効率の低いコンテナを使用するよりも、GetHashCodeを修正する方が適切です。
bmm6o
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.