聊聊C# 中HashTable與Dictionary的區(qū)別說明
1. 哈希表(HashTable)簡述
在.NET Framework中,Hashtable是System.Collections命名空間提供的一個容器,用于處理和表現(xiàn)類似keyvalue的鍵值對,其中key通??捎脕砜焖俨檎?,同時key是區(qū)分大小寫;value用于存儲對應于key的值。Hashtable中keyvalue鍵值對均為object類型,所以Hashtable可以支持任何類型的keyvalue鍵值對.
2. 什么情況下使用哈希表
(1)某些數(shù)據(jù)會被高頻率查詢(2)數(shù)據(jù)量大(3)查詢字段包含字符串類型(4)數(shù)據(jù)類型不唯一
3. 哈希表的使用方法
哈希表需要使用的namespace
using System.Collections; using System.Collections.Generic;
哈希表的基本操作:
//添加一個keyvalue鍵值對: HashtableObject.Add(key,value); //移除某個keyvalue鍵值對: HashtableObject.Remove(key); //移除所有元素: HashtableObject.Clear(); // 判斷是否包含特定鍵key: HashtableObject.Contains(key);
控制臺程序例子:
using System; using System.Collections; //file使用Hashtable時,必須引入這個命名空間 class Program { public static void Main() { Hashtable ht = new Hashtable(); //創(chuàng)建一個Hashtable實例 ht.Add("北京", "帝都"); //添加keyvalue鍵值對 ht.Add("上海", "魔都"); ht.Add("廣州", "省會"); ht.Add("深圳", "特區(qū)"); string capital = (string)ht["北京"]; Console.WriteLine(ht.Contains("上海")); //判斷哈希表是否包含特定鍵,其返回值為true或false ht.Remove("深圳"); //移除一個keyvalue鍵值對 ht.Clear(); //移除所有元素 } }
哈希表中使用多種數(shù)據(jù)類型的例子:
using System; using System.Collections; class Program { static Hashtable GetHashtable() { Hashtable hashtable = new Hashtable(); hashtable.Add("名字", "小麗"); hashtable.Add("年齡", 22); return hashtable; } static void Main() { Hashtable hashtable = GetHashtable(); string name = (string)hashtable["名字"]; Console.WriteLine(name); int age = (int)hashtable["年齡"]; Console.WriteLine(age); } }
當獲取哈希表中數(shù)據(jù)時,如果類型聲明的不對,會出現(xiàn)InvalidCastException錯誤。使用as-statements可以避免該錯誤。
using System; using System.Collections; using System.IO; class Program { static void Main() { Hashtable hashtable = new Hashtable(); hashtable.Add(100, "西安"); // 能轉換成功 string value = hashtable[100] as string; if (value != null) { Console.WriteLine(value); } // 轉換失敗,獲取的值為null,但不會拋出錯誤。 StreamReader reader = hashtable[100] as StreamReader; if (reader == null) { Console.WriteLine("西安不是StreamReader型"); } // 也可以直接獲取object值,再做判斷 object value2 = hashtable[100]; if (value2 is string) { Console.Write("這個是字符串型: "); Console.WriteLine(value2); } } }
4. 遍歷哈希表
遍歷哈希表需要用到DictionaryEntry Object,代碼如下:
for(DictionaryEntry de in ht) //ht為一個Hashtable實例 { Console.WriteLine(de.Key); //de.Key對應于keyvalue鍵值對key Console.WriteLine(de.Value); //de.Key對應于keyvalue鍵值對value }
遍歷鍵
foreach (int key in hashtable.Keys) { Console.WriteLine(key); }
遍歷值
foreach (string value in hashtable.Values) { Console.WriteLine(value); }
5. 對哈希表進行排序
對哈希表按key值重新排列的做法:
ArrayList akeys=new ArrayList(ht.Keys); akeys.Sort(); //按字母順序進行排序 foreach(string key in akeys) { Console.WriteLine(key + ": " + ht[key]); //排序后輸出 }
6. 哈希表的效率
System.Collections下的哈希表(Hashtable)和System.Collections.Generic下的字典(Dictionary)都可用作lookup table,下面比較一下二者的執(zhí)行效率。
Stopwatch sw = new Stopwatch(); Hashtable hashtable = new Hashtable(); Dictionary<string, int> dictionary = new Dictionary<string, int>(); int countNum = 1000000; sw.Start(); for (int i = 0; i < countNum; i++) { hashtable.Add(i.ToString(), i); } sw.Stop(); Console.WriteLine(sw.ElapsedMilliseconds); //輸出: 744 sw.Restart(); for (int i = 0; i < countNum; i++) { dictionary.Add(i.ToString(), i); } sw.Stop(); Console.WriteLine(sw.ElapsedMilliseconds); //輸出: 489 sw.Restart(); for (int i = 0; i < countNum; i++) { hashtable.ContainsKey(i.ToString()); } sw.Stop(); Console.WriteLine(sw.ElapsedMilliseconds); //輸出: 245 sw.Restart(); for (int i = 0; i < countNum; i++) { dictionary.ContainsKey(i.ToString()); } sw.Stop(); Console.WriteLine(sw.ElapsedMilliseconds); //輸出: 192
由此可見,添加數(shù)據(jù)時Hashtable快。頻繁調(diào)用數(shù)據(jù)時Dictionary快。
結論:
Dictionary<K,V>是泛型的,當K或V是值類型時,其速度遠遠超過Hashtable。
補充:C# 哈希表Hashtable與字典表Dictionary<K,V>的比較。
一、Hashtable 和 Dictionary <K, V> 類型
1):單線程程序中推薦使用 Dictionary, 有泛型優(yōu)勢, 且讀取速度較快, 容量利用更充分.
2):多線程程序中推薦使用 Hashtable, 默認的 Hashtable 允許單線程寫入, 多線程讀取, 對 Hashtable 進一步調(diào)用 Synchronized()方法可以獲得完全線程安全的類型. 而Dictionary 非線程安全, 必須人為使用 lock 語句進行保護, 效率大減.
3):Dictionary 有按插入順序排列數(shù)據(jù)的特性 (注: 但當調(diào)用 Remove() 刪除過節(jié)點后順序被打亂), 因此在需要體現(xiàn)順序的情境中使用 Dictionary 能獲得一定方便.
在使用哈希表保存集合元素(一種鍵/值對)時,首先要根據(jù)鍵自動計算哈希代碼,以確定該元素的保存位置,再把元素的值放入相應位置所指向的存儲桶中。在查找時,再次通過鍵所對應的哈希代碼到特定存儲桶中搜索,這樣將大大減少為查找一個元素進行比較的次數(shù)。
HashTable中的key/value均為object類型,由包含集合元素的存儲桶組成。存儲桶是 HashTable中各元素的虛擬子組,與大多數(shù)集合中進行的搜索和檢索相比,存儲桶可令搜索和檢索更為便捷。每一存儲桶都與一個哈希代碼關聯(lián),該哈希代碼是使用哈希函數(shù)生成的并基于該元素的鍵。HashTable的優(yōu)點就在于其索引的方式,速度非???。如果以任意類型鍵值訪問其中元素會快于其他集合,特別是當數(shù)據(jù)量特別大的時候,效率差別尤其大。
HashTable的應用場合有:做對象緩存,樹遞歸算法的替代,和各種需提升效率的場合。
二、哈希表Hashtabl
Hastable是哈希表的實現(xiàn),能根據(jù)關鍵字取關鍵值,這key的類型是object, value的類型也是object。
在哈希表中添加一個key/value鍵值對:HashtableObject.Add(key,value);
在哈希表中去除某個key/value鍵值對:HashtableObject.Remove(key);
從哈希表中移除所有元素: HashtableObject.Clear();
判斷哈希表是否包含特定鍵key: HashtableObject.Contains(key);
遍歷Hashtable對象的兩種方法:
由于Hashtable每個元素都是一個鍵/值對,因此元素類型既不是鍵的類型,也不是值的類型,而是DictionaryEntry類型。
Hashtable示例代碼
<pre name="code" class="csharp">Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->//方法一 foreach (System.Collections.DictionaryEntry de in myHashtable) { //注意HastTable內(nèi)存儲的默認類型是object,需要進行轉換才可以輸出 Console.WriteLine(de.Key.ToString()); Console.WriteLine(de.Value.ToString()); } //方法二 System.Collections.IDictionaryEnumerator enumerator = myHashtable.GetEnumerator(); while (enumerator.MoveNext()) { Console.WriteLine(enumerator.Key); // Hashtable關健字 Console.WriteLine(enumerator.Value); // Hashtable值 }
三、字典Dictionary
Dictionary<Tkey,Tvalue>是Hastbale的泛型實現(xiàn)。
<span style="font-size:18px;">Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->//遍歷鍵 foreach (string key in myDictionary.Keys) { //遍歷某鍵的值 foreach (string val in myDictionary[key]) { } }</span>
由于 Dictionary 是鍵和值的集合,因此元素類型并非鍵類型或值類型。相反,元素類型是鍵類型和值類型的 KeyValuePair 。
<span style="font-size:18px;">字典遍歷示例 Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->foreach (KeyValuePair<string, string> kvp in myDictionary) { string key = kvp.Key;//key包含了字典里的鍵 for (int i = 0; i < kvp.Value.Count; i++) { Response.Write(kvp.Value[i]); } }</span>
示例 :
代碼
Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->//定義一個<string,int>的Dictionary,讓它的值進行添加(也可以用Add方法) Dictionary<string, int> dic = new Dictionary<string, int>(); //添加兩個鍵為"成績1","成績2";并為它們的值賦為0 dic["成績1"] = 0; dic["成績2"] = 0; // 把這兩個值分別加1 dic["成績1"]++; dic["成績2"]++;
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。如有錯誤或未考慮完全的地方,望不吝賜教。
相關文章
C#實現(xiàn)創(chuàng)建標簽PDF文件的示例代碼
標簽PDF文件包含描述文檔結構和各種文檔元素順序的元數(shù)據(jù),是一種包含后端提供的可訪問標記,管理閱讀順序和文檔內(nèi)容表示的邏輯結構的PDF文件。本文將用C#實現(xiàn)創(chuàng)建標簽PDF文件,需要的可以參考一下2022-08-08c#只讀字段和常量的區(qū)別,以及靜態(tài)構造函數(shù)的使用實例
這篇文章主要介紹了c#只讀字段和常量的區(qū)別,以及靜態(tài)構造函數(shù)的使用實例,有需要的朋友可以參考一下2013-12-12基于Unity Line Renderer組件的常用屬性說明
這篇文章主要介紹了基于Unity Line Renderer組件的常用屬性說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-04-04詳解C#中 Thread,Task,Async/Await,IAsyncResult的那些事兒
本文主要介紹了C#中 Thread,Task,Async/Await,IAsyncResult的相關知識。具有一定的參考價值,下面跟著小編一起來看下吧2017-01-01