C # Set koleksi?

488

Apakah ada yang tahu jika ada yang setara dengan Setkoleksi Java di C #? Saya tahu bahwa Anda bisa meniru set menggunakan a Dictionaryatau a HashTabledengan mengisi tetapi mengabaikan nilai-nilai, tapi itu bukan cara yang sangat elegan.

Omar Kooheji
sumber

Jawaban:

142

Coba HashSet :

Kelas HashSet (Of T) menyediakan operasi set berkinerja tinggi. Kumpulan adalah kumpulan yang tidak mengandung elemen duplikat, dan yang elemennya tidak ada dalam urutan tertentu ...

Kapasitas objek HashSet (Of T) adalah jumlah elemen yang dapat dipegang oleh objek tersebut. Kapasitas objek HashSet (Of T) secara otomatis meningkat ketika elemen ditambahkan ke objek.

Kelas HashSet (Of T) didasarkan pada model set matematika dan menyediakan operasi set berkinerja tinggi mirip dengan mengakses kunci Kamus (Of TKey, TValue) atau koleksi Hashtable . Dalam istilah sederhana, kelas HashSet (Of T) dapat dianggap sebagai koleksi Kamus (Of TKey, TValue) tanpa nilai.

Koleksi HashSet (Of T) tidak diurutkan dan tidak dapat berisi elemen duplikat ...

Leahn Novash
sumber
8
Sayangnya, HashSets tidak ditambahkan sampai baru-baru ini. Jika Anda bekerja dalam versi kerangka yang lebih lama, Anda harus tetap menggunakan Kamus munged Anda <> atau Hashtable.
Greg D
413

Jika Anda menggunakan .NET 3.5, Anda bisa menggunakan HashSet<T>. Memang benar bahwa .NET tidak melayani set dan Java tidak.

The Wintellect PowerCollections dapat membantu juga.

Jon Skeet
sumber
16
Saya menduga bahwa Set adalah kata kunci dalam beberapa bahasa, yang dapat menyebabkan masalah.
Jon Skeet
3
@ Bahasa Spanyol: Tidak, bukan itu. Lihat bagian 2.4.3 dari spesifikasi C # 3. Hanya memiliki arti khusus untuk properti.
Jon Skeet
28
Alasan untuk menyebutnya HashSet, bukan hanya Set, adalah sama dengan di Jawa- "Set" menggambarkan sebuah antarmuka, sedangkan "HashSet" menggambarkan implementasi-khusus, ini adalah Set yang didukung oleh Peta Hash. Dengan cara ini, kita tahu (atau harus sangat berharap) bahwa insert dan akses harus mengambil O (1) waktu akses, vs "LinkedListSet" yang akan mengarahkan kita untuk mengharapkan insert dan akses untuk mengambil waktu O (n).
David Souther
5
apa maksudmu ". NET tidak melayani set seperti halnya Java."? Apakah Perangkat ini entah bagaimana tidak sempurna dibandingkan dengan Java?
Louis Rhys
34
@ Louis: Set mana yang kamu bicarakan? Java memiliki banyak implementasi Set yang berbeda untuk berbagai situasi. .NET memiliki satu di .NET 3.5 (HashSet) dan dua di .NET 4 (HashSet dan SortedSet). Fakta bahwa kami harus menunggu sampai. NET 3.5 untuk memulai cukup mengejutkan.
Jon Skeet
26

Jika Anda menggunakan .NET 4.0 atau yang lebih baru:

Jika Anda perlu menyortir, gunakan SortedSet<T>. Kalau tidak, jika tidak, gunakan HashSet<T>karena itu O(1)untuk mencari dan memanipulasi operasi. Sedangkan SortedSet<T>adalah O(log n)untuk pencarian dan memanipulasi operasi.

Derek W
sumber
13

Saya menggunakan pembungkus di sekitar a Dictionary<T, object>, menyimpan nulls dalam nilai-nilai. Ini memberi O (1) menambah, mencari dan menghapus pada tombol, dan untuk semua maksud dan tujuan bertindak seperti satu set.

thecoop
sumber
2
Anda harus mengartikannya kira-kira setara dengan std :: unordered_set. std :: set dipesan. Misalnya, Anda dapat dengan cepat menemukan titik awal dan akhir rentang dan beralih dari awal hingga akhir, mengunjungi item dalam urutan kunci. SortedDictionary kira - kira setara dengan std :: set.
doug65536
11

Lihat PowerCollections di CodePlex. Selain dari Set dan OrderedSet, ia memiliki beberapa jenis koleksi berguna lainnya seperti Deque, MultiDictionary, Bag, OrderedBag, OrderedDictionary dan OrderedMultiDictionary.

Untuk koleksi lainnya, ada juga Perpustakaan Koleksi Generik C5 .

dpan
sumber
-5

Saya tahu ini adalah utas lama, tetapi saya mengalami masalah yang sama dan menemukan HashSet sangat tidak dapat diandalkan karena diberi benih yang sama, GetHashCode () mengembalikan kode yang berbeda. Jadi, saya pikir, mengapa tidak hanya menggunakan Daftar dan menyembunyikan metode add seperti ini

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

Karena Daftar menggunakan metode Persamaan hanya untuk menentukan kesetaraan, Anda dapat menentukan metode Persamaan pada tipe T Anda untuk memastikan Anda mendapatkan hasil yang diinginkan.

Bob Heck
sumber
13
Alasan Anda tidak ingin menggunakan ini karena List.Containsadalah O(n)kompleksitas yang berarti bahwa Anda Addmetode sekarang menjadi O(n)kompleksitas juga. Dengan asumsi koleksi batin tidak perlu diubah ukurannya, Adduntuk keduanya Listdan HashMapharus O(1)rumit. TLDR: Ini akan berhasil, tetapi ini peretasan dan kurang efisien.
Richard Marskell - Drackir
6
Tentu, jika objek Anda tidak mengembalikan nilai yang sesuai untuk GetHashCode, Anda tidak harus memasukkannya ke dalam wadah berbasis hash. Akan lebih baik untuk memperbaiki GetHashCode daripada menggunakan wadah yang kurang efisien.
bmm6o