Bagikan melalui


Koleksi dan Struktur Data

Data serupa sering dapat ditangani lebih efisien ketika disimpan dan dimanipulasi sebagai koleksi. Anda dapat menggunakan System.Array kelas atau kelas di System.Collectionsnamespace , , System.Collections.GenericSystem.Collections.Concurrent, dan System.Collections.Immutable untuk menambahkan, menghapus, dan memodifikasi elemen individual atau rentang elemen dalam koleksi.

Ada dua jenis koleksi utama; koleksi generik dan koleksi non-generik. Koleksi generik berjenis aman pada waktu kompilasi. Karena itu, koleksi generik biasanya menawarkan performa yang lebih baik. Koleksi generik menerima parameter jenis saat dibuat. Mereka tidak mengharuskan Anda untuk mengonversi tipe Object saat menambahkan atau menghapus item dari koleksi. Selain itu, sebagian besar koleksi generik didukung di aplikasi Windows Store. Koleksi non-generik menyimpan item sebagai Object, memerlukan transmisi, dan sebagian besar tidak didukung untuk pengembangan aplikasi Windows Store. Namun, Anda mungkin melihat koleksi tidak generik dalam kode yang lebih lama.

Di .NET Framework 4 dan versi yang lebih baru, koleksi di System.Collections.Concurrent namespace menyediakan operasi aman utas yang efisien untuk mengakses item koleksi dari beberapa utas. Kelas koleksi tak berubah di namespace System.Collections.Immutable (paket NuGet) dengan sendirinya aman terhadap utas karena operasi dilakukan pada salinan koleksi asli, dan koleksi asli tidak dapat dimodifikasi.

Fitur koleksi umum

Semua koleksi menyediakan metode untuk menambahkan, menghapus, atau menemukan item dalam koleksi. Selain itu, semua koleksi yang secara langsung atau tidak langsung mengimplementasikan ICollection antarmuka atau ICollection<T> antarmuka berbagi fitur-fitur ini:

Selain itu, banyak kelas koleksi berisi fitur-fitur berikut:

  • Properti Kapasitas dan Jumlah

    Kapasitas koleksi adalah jumlah elemen yang dapat dikandungnya. Jumlah koleksi adalah jumlah elemen yang sebenarnya dikandungnya. Beberapa koleksi menyembunyikan kapasitas atau hitungan atau keduanya.

    Sebagian besar koleksi secara otomatis memperluas kapasitas ketika kapasitas saat ini tercapai. Memori direalokasikan, dan elemen disalin dari koleksi lama ke yang baru. Desain ini mengurangi kode yang diperlukan untuk menggunakan koleksi. Namun, performa koleksi mungkin terpengaruh secara negatif. Misalnya, untuk List<T>, jika Count kurang dari Capacity, menambahkan item adalah operasi O(1). Jika kapasitas perlu ditingkatkan untuk mengakomodasi elemen baru, menambahkan item menjadi operasi O(n), di mana n adalah Count. Cara terbaik untuk menghindari performa buruk yang disebabkan oleh beberapa realokasi adalah dengan mengatur kapasitas awal menjadi ukuran perkiraan koleksi.

    A BitArray adalah kasus khusus; kapasitasnya sama dengan panjangnya, yang sama dengan hitungannya.

  • Batas bawah yang konsisten

    Batas bawah koleksi adalah indeks elemen pertamanya. Semua koleksi terindeks di System.Collections namespace memiliki batas nol yang lebih rendah, yang berarti mereka diindeks 0. Array memiliki batas nol yang lebih rendah secara default, tetapi batas bawah yang berbeda dapat ditentukan saat membuat instans kelas Array menggunakan Array.CreateInstance.

  • Sinkronisasi untuk akses dari beberapa utas (System.Collections hanya untuk kelas).

    Jenis koleksi non-generik di System.Collections namespace memberikan beberapa keamanan utas dengan sinkronisasi; biasanya diekspos melalui anggota SyncRoot dan IsSynchronized. Koleksi ini tidak aman secara default. Jika Anda memerlukan akses multi-utas yang efisien dan dapat diskalakan ke koleksi, gunakan salah satu kelas di namespace System.Collections.Concurrent atau pertimbangkan untuk menggunakan koleksi tak dapat diubah. Untuk informasi selengkapnya, lihat KoleksiThread-Safe.

Pilih koleksi

Secara umum, Anda harus menggunakan koleksi generik. Tabel berikut ini menjelaskan beberapa skenario koleksi umum dan kelas koleksi yang dapat Anda gunakan untuk skenario tersebut. Jika Anda baru menggunakan koleksi generik, tabel berikut ini akan membantu Anda memilih koleksi generik yang paling sesuai untuk tugas Anda:

Saya juga mau... Opsi koleksi generik Opsi koleksi non-generik Opsi pengumpulan aman utas atau tidak dapat diubah
Simpan item sebagai pasangan kunci/nilai untuk pencarian cepat menurut kunci Dictionary<TKey,TValue> Hashtable

(Kumpulan pasangan kunci/nilai yang diatur berdasarkan kode hash kunci.)
ConcurrentDictionary<TKey,TValue>

ReadOnlyDictionary<TKey,TValue>

ImmutableDictionary<TKey,TValue>
Mengakses item menurut indeks List<T> Array

ArrayList
ImmutableList<T>

ImmutableArray
Gunakan item dengan metode masuk pertama, keluar pertama (FIFO) Queue<T> Queue ConcurrentQueue<T>

ImmutableQueue<T>
Menggunakan data Last-In-First-Out (LIFO) Stack<T> Stack ConcurrentStack<T>

ImmutableStack<T>
Mengakses item secara berurutan LinkedList<T> Tidak ada rekomendasi Tidak ada rekomendasi
Terima pemberitahuan ketika item dihapus atau ditambahkan ke koleksi. (mengimplementasikan INotifyPropertyChanged dan INotifyCollectionChanged) ObservableCollection<T> Tidak ada rekomendasi Tidak ada rekomendasi
Kumpulan yang diurutkan SortedList<TKey,TValue> SortedList ImmutableSortedDictionary<TKey,TValue>

ImmutableSortedSet<T>
Himpunan untuk fungsi matematika HashSet<T>

SortedSet<T>
Tidak ada rekomendasi ImmutableHashSet<T>

ImmutableSortedSet<T>

Kompleksitas algoritma koleksi

Saat memilih kelas koleksi, ada baiknya mempertimbangkan potensi kompromi dalam performa. Gunakan tabel berikut untuk melihat perbandingan bagaimana berbagai koleksi yang bisa diubah dibandingkan dalam kompleksitas algoritma dengan koleksi yang tidak dapat diubah yang sepadan. Seringkali jenis koleksi yang tidak dapat diubah kurang berkinerja tetapi memberikan imutabilitas - yang seringkali merupakan manfaat komparatif yang valid.

Dapat diubah Diamortisasi Kasus Terburuk Tidak Berubah Kompleksitas
Stack<T>.Push O(1) O(n) ImmutableStack<T>.Push O(1)
Queue<T>.Enqueue O(1) O(n) ImmutableQueue<T>.Enqueue O(1)
List<T>.Add O(1) O(n) ImmutableList<T>.Add O(log n)
List<T>.Item[Int32] O(1) O(1) ImmutableList<T>.Item[Int32] O(log n)
List<T>.Enumerator O(n) O(n) ImmutableList<T>.Enumerator O(n)
HashSet<T>.AddLookup O(1) O(n) ImmutableHashSet<T>.Add O(log n)
SortedSet<T>.Add O(log n) O(n) ImmutableSortedSet<T>.Add O(log n)
Dictionary<T>.Add O(1) O(n) ImmutableDictionary<T>.Add O(log n)
Dictionary<T> Pencarian O(1) O(1) – atau persis O(n) ImmutableDictionary<T> Pencarian O(log n)
SortedDictionary<T>.Add O(log n) O(n log n) ImmutableSortedDictionary<T>.Add O(log n)

List<T> Dapat dijumlahkan secara efisien menggunakan perulangan for atau perulanganforeach. Namun, ImmutableList<T> melakukan pekerjaan yang kurang baik di dalam perulangan for, karena waktu O(log n) untuk pengindeksannya. Enumerasi ImmutableList<T> menggunakan perulangan foreach efisien karena ImmutableList<T> menggunakan pohon biner untuk menyimpan datanya alih-alih array yang digunakan oleh List<T>. Array dapat dengan cepat diindeks, sedangkan pohon biner harus dijalani hingga simpul dengan indeks yang diinginkan ditemukan.

Selain itu, SortedSet<T> memiliki kompleksitas yang sama seperti ImmutableSortedSet<T> karena keduanya menggunakan pohon biner. Perbedaan signifikannya adalah menggunakan ImmutableSortedSet<T> pohon biner yang tidak dapat diubah. Karena ImmutableSortedSet<T> juga menawarkan System.Collections.Immutable.ImmutableSortedSet<T>.Builder kelas yang memungkinkan mutasi, Anda dapat memiliki kekekalan dan performa.

Judul Deskripsi
Memilih Kelas Koleksi Menjelaskan berbagai koleksi dan membantu Anda memilih satu untuk skenario Anda.
Jenis Koleksi yang Umum Digunakan Menjelaskan jenis koleksi generik dan non-generik yang umum digunakan seperti System.Array, , System.Collections.Generic.List<T>dan System.Collections.Generic.Dictionary<TKey,TValue>.
Kapan Menggunakan Koleksi Generik Membahas penggunaan jenis koleksi generik.
Perbandingan dan Pengurutan Dalam Koleksi Membahas penggunaan perbandingan kesetaraan dan perbandingan pengurutan dalam koleksi.
Tipe Koleksi Yang Diurutkan Menjelaskan performa dan karakteristik koleksi yang diurutkan.
Jenis Koleksi Hashtable dan Kamus Menjelaskan fitur jenis kamus berbasis hash generik dan non-generik.
Thread-Safe Koleksi Menjelaskan jenis koleksi seperti System.Collections.Concurrent.BlockingCollection<T> dan System.Collections.Concurrent.ConcurrentBag<T> yang mendukung akses bersamaan dari beberapa utas secara aman dan efisien.
System.Collections.Immutable Memperkenalkan koleksi yang tidak dapat diubah dan menyediakan tautan ke jenis koleksi.

Referensi