Di sebagian besar bahasa pemrograman, kamus lebih disukai daripada tagar. Apa alasan di balik itu?
c#
.net
vb.net
data-structures
Nakul Chaudhary
sumber
sumber
Dictionary
itu adalah implementasi dariHashtable
.HashTable
. Ketika mereka menambahkan obat generik ke bahasa tersebut, mereka menyebut versi generikDictionary
. Keduanya adalah tabel hash.Jawaban:
Untuk apa nilainya, Kamus adalah (secara konseptual) tabel hash.
Jika Anda bermaksud "mengapa kita menggunakan
Dictionary<TKey, TValue>
kelas dan bukanHashtable
kelas?", Maka itu adalah jawaban yang mudah:Dictionary<TKey, TValue>
adalah tipe generik,Hashtable
bukan. Itu berarti Anda mendapatkan keamanan jenisDictionary<TKey, TValue>
, karena Anda tidak dapat memasukkan objek acak apa pun ke dalamnya, dan Anda tidak harus membuang nilai yang Anda ambil.Menariknya,
Dictionary<TKey, TValue>
implementasi dalam .NET Framework didasarkan padaHashtable
, seperti yang Anda tahu dari komentar ini dalam kode sumbernya:Sumber
sumber
HashTable
(kelas) danDictionary
(kelas) adalah tabel hash (konsep), tetapi aHashTable
bukan aDictionary
, juga bukanDictionary
aHashTable
. Mereka digunakan dalam mode yang sangat mirip, danDictionary<Object,Object>
dapat bertindak dengan cara yangHashTable
tidak diketik sama seperti yang dilakukan, tetapi mereka tidak secara langsung berbagi kode apa pun (meskipun bagian kemungkinan akan diterapkan dengan cara yang sangat mirip).Dictionary
<<< >>>Hashtable
perbedaan:Synchronized()
metodeKeyValuePair
dihitung : <<< >>> Item yang dihitung:DictionaryEntry
Dictionary
/Hashtable
kesamaan:GetHashCode()
metode sendiriKoleksi .NET yang serupa (kandidat untuk digunakan alih-alih Kamus dan Hashtable):
ConcurrentDictionary
- Utas aman (dapat diakses dengan aman dari beberapa utas secara bersamaan)HybridDictionary
- Kinerja yang dioptimalkan (untuk beberapa item dan juga untuk banyak item)OrderedDictionary
- nilai dapat diakses melalui indeks int (berdasarkan urutan penambahan item)SortedDictionary
- item diurutkan secara otomatisStringDictionary
- sangat diketik dan dioptimalkan untuk stringsumber
StringDictionary
... btwStringDictionary
tidak sama denganDictionary<string, string>
ketika Anda menggunakan konstruktor default.Karena
Dictionary
adalah kelas generik (Dictionary<TKey, TValue>
), sehingga mengakses kontennya adalah tipe-aman (yaitu Anda tidak perlu menggunakanObject
, seperti yang Anda lakukan dengan aHashtable
).Membandingkan
untuk
Namun,
Dictionary
diimplementasikan sebagai tabel hash secara internal, jadi secara teknis ia bekerja dengan cara yang sama.sumber
FYI: Di .NET,
Hashtable
adalah utas yang aman untuk digunakan oleh banyak pembaca utas dan utas tunggal, sementara diDictionary
anggota statis publik adalah utas aman, tetapi setiap anggota contoh tidak dijamin aman utas.Kami harus mengubah semua Kamus kami kembali
Hashtable
karena ini.sumber
ConcurrentDictionary
kelas yang menerapkan semua metode publik / terlindungi agar aman. Jika Anda tidak perlu mendukung platform lawas, ini akan memungkinkan Anda menggantiHashtable
kode multithreaded: msdn.microsoft.com/en-us/library/dd287191.aspxDi .NET, perbedaan antara
Dictionary<,>
danHashTable
terutama bahwa yang pertama adalah tipe generik, sehingga Anda mendapatkan semua manfaat dari generik dalam hal pemeriksaan tipe statis (dan mengurangi tinju, tapi ini tidak sebesar yang orang cenderung berpikir dalam dalam hal kinerja - ada biaya memori yang pasti untuk tinju, meskipun).sumber
Orang-orang mengatakan bahwa Kamus sama dengan tabel hash.
Ini belum tentu benar. Tabel hash adalah salah satu cara untuk mengimplementasikan kamus. Yang tipikal pada saat itu, dan itu mungkin yang standar di .NET di
Dictionary
kelas, tapi itu bukan satu-satunya definisi.Anda juga dapat mengimplementasikan kamus menggunakan daftar tautan atau pohon pencarian dengan baik, itu tidak akan seefisien (untuk beberapa metrik efisien).
sumber
Dictionary<K,V>
.IDictionary<K,V>
bisa jadi apa saja :)Collections
&Generics
berguna untuk menangani kelompok objek. Di .NET, semua objek koleksi berada di bawah antarmukaIEnumerable
, yang pada gilirannya memilikiArrayList(Index-Value))
&HashTable(Key-Value)
. Setelah .NET framework 2.0,ArrayList
&HashTable
diganti denganList
&Dictionary
. Sekarang,Arraylist
&HashTable
tidak lagi digunakan dalam proyek saat ini.Datang ke perbedaan antara
HashTable
&Dictionary
,Dictionary
adalah generik di manaHastable
tidak generik. Kita dapat menambahkan semua jenis objekHashTable
, tetapi saat mengambil kita perlu melemparkannya ke jenis yang diperlukan. Jadi, ini bukan tipe yang aman. Tetapi untukdictionary
, saat mendeklarasikan sendiri, kita dapat menentukan jenis kunci dan nilai, sehingga tidak perlu digunakan saat mengambil.Mari kita lihat sebuah contoh:
HashTable
Kamus,
sumber
Kamus:
Mengembalikan / melempar Pengecualian jika kami mencoba menemukan kunci yang tidak ada.
Ini lebih cepat daripada Hashtable karena tidak ada tinju dan unboxing.
Hanya anggota statis publik yang aman utas.
Kamus adalah tipe generik yang berarti kita dapat menggunakannya dengan tipe data apa pun (Saat membuat, harus menentukan tipe data untuk kunci dan nilai).
Contoh:
Dictionary<string, string> <NameOfDictionaryVar> = new Dictionary<string, string>();
Dictionay adalah implementasi Hashtable yang aman untuk tipe,
Keys
danValues
sangat diketik.Hashtable:
Ia mengembalikan nol jika kami mencoba menemukan kunci yang tidak ada.
Ini lebih lambat daripada kamus karena membutuhkan tinju dan unboxing.
Semua anggota di Hashtable aman,
Hashtable bukan tipe generik,
Hashtable adalah struktur data yang diketik secara longgar, kita dapat menambahkan kunci dan nilai dari jenis apa pun.
sumber
Dictionary.TryGetValue
The Pemeriksaan luas dari Struktur Data Menggunakan C # artikel di MSDN menyatakan bahwa ada juga perbedaan dalam strategi resolusi tabrakan :
Kelas Hashtable menggunakan teknik yang disebut sebagai rehashing .
Kamus menggunakan teknik yang disebut chaining .
sumber
Sejak .NET Framework 3.5 ada juga
HashSet<T>
yang menyediakan semua kelebihanDictionary<TKey, TValue>
jika Anda hanya perlu kunci dan tidak ada nilai.Jadi, jika Anda menggunakan
Dictionary<MyType, object>
dan selalu menetapkan nilainull
untuk mensimulasikan tabel hash jenis aman Anda mungkin harus mempertimbangkan beralih keHashSet<T>
.sumber
Ini
Hashtable
adalah struktur data yang diketik secara longgar, sehingga Anda dapat menambahkan kunci dan nilai dari jenis apa pun keHashtable
. TheDictionary
kelas adalah jenis-amanHashtable
implementasi, dan tombol dan nilai-nilai yang sangat diketik. Saat membuatDictionary
contoh, Anda harus menentukan tipe data untuk kunci dan nilai.sumber
Perhatikan bahwa MSDN mengatakan: "Kamus <(Dari <(TKey, TValue>)>) kelas diimplementasikan sebagai tabel hash ", bukan "Kamus <(Dari <(TKey, TValue>)>) kelas diimplementasikan sebagai HashTable "
Kamus TIDAK diimplementasikan sebagai HashTable, tetapi diimplementasikan mengikuti konsep tabel hash. Implementasi tidak terkait dengan kelas HashTable karena penggunaan Generics, meskipun secara internal Microsoft bisa menggunakan kode yang sama dan mengganti simbol tipe Object dengan TKey dan TValue.
Di .NET 1.0 Generik tidak ada; ini adalah tempat HashTable dan ArrayList awalnya dimulai.
sumber
HashTable:
Kunci / nilai akan dikonversi menjadi tipe objek (tinju) saat menyimpan ke heap.
Kunci / nilai perlu dikonversi ke jenis yang diinginkan saat membaca dari tumpukan.
Operasi ini sangat mahal. Kita harus menghindari tinju / unboxing sebanyak mungkin.
Kamus: Varian umum dari HashTable.
Tidak ada tinju / unboxing. Tidak perlu konversi.
sumber
Objek Hashtable terdiri dari ember yang berisi elemen koleksi. Bucket adalah subkelompok elemen virtual dalam Hashtable, yang membuat pencarian dan pengambilan lebih mudah dan lebih cepat daripada di sebagian besar koleksi .
Kelas Kamus memiliki fungsi yang sama dengan kelas Hashtable. Kamus jenis tertentu (selain Obyek) memiliki kinerja yang lebih baik daripada Hashtable untuk jenis nilai karena unsur-unsur Hashtable adalah tipe Objek dan, oleh karena itu, tinju dan unboxing biasanya terjadi jika menyimpan atau mengambil jenis nilai.
Untuk bacaan lebih lanjut: Jenis Koleksi Kamus dan Hashtable
sumber
Perbedaan penting lainnya adalah bahwa Hashtable aman untuk digunakan. Hashtable memiliki keamanan utas pembaca multi / penulis tunggal (MR / SW) yang berarti Hashtable memungkinkan SATU penulis bersama dengan banyak pembaca tanpa mengunci.
Dalam kasus Kamus tidak ada keamanan utas; jika Anda memerlukan keamanan utas, Anda harus menerapkan sinkronisasi Anda sendiri.
Untuk menguraikan lebih lanjut:
Jika Anda perlu mengetikkan keamanan juga keamanan utas, gunakan kelas koleksi bersamaan di .NET Framework. Bacaan lebih lanjut di sini .
Perbedaan tambahan adalah bahwa ketika kita menambahkan beberapa entri dalam Kamus, urutan penambahan entri dipertahankan. Ketika kami mengambil item dari Kamus kami akan mendapatkan catatan dalam urutan yang sama seperti yang kami masukkan. Sedangkan Hashtable tidak mempertahankan urutan penyisipan.
sumber
Hashset
jaminan keamanan MR / SW thread dalam skenario penggunaan yang tidak melibatkan penghapusan . Saya pikir itu mungkin dimaksudkan untuk sepenuhnya aman MR / SW, tetapi menangani penghapusan dengan aman sangat meningkatkan biaya keselamatan MR / SW. Sementara desainDictionary
bisa menawarkan keamanan MR / SW dengan biaya minimal dalam skenario tanpa-hapus, saya pikir MS ingin menghindari memperlakukan skenario tanpa-hapus sebagai "istimewa".Satu lagi perbedaan yang bisa saya pahami adalah:
Kami tidak dapat menggunakan Kamus <KT, VT> (generik) dengan layanan web. Alasannya adalah tidak ada standar layanan web yang mendukung standar generik.
sumber
Dictionary<>
adalah tipe generik dan tipe aman.Anda bisa menyisipkan tipe nilai apa pun di HashTable dan ini kadang-kadang bisa menimbulkan pengecualian. Tetapi
Dictionary<int>
hanya akan menerima nilai integer dan jugaDictionary<string>
hanya akan menerima string.Jadi, lebih baik menggunakan
Dictionary<>
daripadaHashTable
.sumber
Saya tidak berpikir ini benar, sebagian besar bahasa memiliki satu atau yang lain, tergantung pada terminologi yang mereka sukai .
Dalam C #, bagaimanapun, alasan yang jelas (bagi saya) adalah bahwa C # HashTables dan anggota lain dari System.Collections namespace sebagian besar sudah usang. Mereka hadir di c # V1.1. Mereka telah digantikan dari C # 2.0 oleh kelas Generic di System.Collections. namespace General.
sumber
Menurut apa yang saya lihat dengan menggunakan .NET Reflector :
Jadi kita dapat yakin bahwa DictionaryBase menggunakan HashTable secara internal.
sumber