C # Set koleksiyonu?


488

Herkes Java'nın SetC # koleksiyonuna iyi bir eşdeğer olup olmadığını biliyor mu ? Bir kümesi a Dictionaryveya a kullanarak HashTabledoldurup değerleri göz ardı ederek biraz taklit edebileceğinizi biliyorum , ama bu çok zarif bir yol değil.

Yanıtlar:


142

HashSet'i deneyin :

HashSet (Of T) sınıfı yüksek performanslı set işlemleri sağlar. Küme, yinelenen öğe içermeyen ve öğeleri belirli bir sırada olmayan bir koleksiyon ...

HashSet (Of T) nesnesinin kapasitesi, nesnenin tutabileceği öğe sayısıdır. HashSet (Of T) nesnesinin kapasitesi, nesneye öğeler eklendikçe otomatik olarak artar.

HashSet (Of T) sınıfı, matematiksel kümelerin modelini temel alır ve Dictionary (TKey, TValue) veya Hashtable koleksiyonlarının anahtarlarına erişmeye benzer yüksek performanslı küme işlemleri sağlar . Basit bir ifadeyle, HashSet (Of T) sınıfı değer içermeyen bir Dictionary (Of TKey, TValue) koleksiyonu olarak düşünülebilir .

Bir HashSet (Of T) koleksiyonu sıralanmaz ve yinelenen öğeler içeremez ...


8
Ne yazık ki, HashSets yakın zamana kadar eklenmedi. Çerçevenin daha eski bir sürümünde çalışıyorsanız, munged Dictionary <> ya da Hashtable'ınıza bağlı kalmanız gerekir.
Greg D

413

.NET 3.5 kullanıyorsanız, kullanabilirsiniz HashSet<T>. .NET'in Java'nın yanı sıra setlere hitap etmediği doğrudur.

Wintellect PowerCollections çok yardımcı olabilir.


16
Set'in bazı dillerde, anahtar kelimelere neden olabilecek bir anahtar kelime olduğundan şüpheleniyorum.
Jon Skeet

3
@Manish: Hayır, değil. C # 3 spesifikasyonunun 2.4.3 bölümüne bakın. Sadece mülkler için özel bir anlamı vardır.
Jon Skeet

28
Bunu sadece Set yerine HashSet olarak adlandırmanın nedeni Java'daki ile aynıdır- "Set" bir arabirimi açıklarken, "HashSet" bir uygulamayı açıklar - özellikle bu bir Hash Map tarafından desteklenen bir Settir. Bu şekilde, ekleme ve erişimin O (1) erişim süresi alması gerektiğini biliyoruz (veya kesinlikle beklemeliyiz).
David Souther

5
ne demek ".NET olsa Java yanı sıra setleri için hitap değil"? Bu Set Java ile karşılaştırıldığında bir şekilde kusurlu mu?
Louis Rhys

34
@ Louis: Hangi Setten bahsediyorsun? Java'nın çeşitli durumlar için Set'in birçok farklı uygulaması vardır. .NET'in biri .NET 3.5'te (HashSet) ve ikisi .NET 4'te (HashSet ve SortedSet) vardı. Başlamak için .NET 3.5'e kadar beklemek zorunda kalmamız oldukça şaşırtıcı.
Jon Skeet

26

.NET 4.0 veya üstünü kullanıyorsanız:

Sıralama yapmanız gereken durumda kullanın SortedSet<T>. Aksi Aksi takdirde, o zaman kullanmak HashSet<T>Çünkü o O(1)arama için ve operasyonları manipüle. Oysa SortedSet<T>olduğu O(log n)arama için ve operasyonları manipüle.



13

Dictionary<T, object>Değerleri içinde null'ları depolayan bir paketleyici kullanıyorum . Bu, O (1) tuşlarına ekleme, arama ve kaldırma sağlar ve tüm niyet ve amaçlara küme gibi davranır.


2
Bunun kabaca std :: unordered_set ile eşdeğer olduğunu belirtmelisiniz. std :: set sipariş edilir. Örneğin, bir aralığın başlangıç ​​ve bitiş noktasını hızlı bir şekilde bulabilir ve öğeleri anahtar sırayla ziyaret ederek baştan sona yineleyebilirsiniz. SortedDictionary olduğu std :: kümesine kabaca.
doug65536


-5

Bu eski bir iş parçacığı olduğunu biliyorum, ama aynı soruna koşuyordu ve aynı tohum verildiğinde GetHashCode () farklı kodlar döndü çünkü HashSet çok güvenilmez bulundu. Bu yüzden, neden sadece bir Liste kullanmak ve bu şekilde ekleme yöntemini gizlemek değil diye düşündüm

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

Liste yalnızca eşitliği belirlemek için Eşittir yöntemini kullandığından, istediğiniz sonucu aldığınızdan emin olmak için T türünüzde Eşittir yöntemini tanımlayabilirsiniz.


13
Çünkü bu kullanmak istemem nedeni List.Containstaşımaktadır O(n)sizin demekse karmaşıklık Addyöntemi şimdi olur O(n)sıra karmaşıklığı. İç koleksiyon varsayarsak, yeniden boyutlandırılabilir gerekmez Addikisi için Listve HashMapolmalıdır O(1)karmaşıklığı. TLDR: Bu işe yarayacak, ancak hileli ve daha az verimli.
Richard Marskell - Drackir

6
Elbette, nesneleriniz GetHashCode için uygun bir değer döndürmezse, bunları karma tabanlı bir kaba koymamalısınız. GetHashCode'u düzeltmek, daha az verimli bir kap kullanmaktan daha iyidir.
5mm12
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.