溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

HashTable與Dictionary在C# 中有什么區(qū)別

發(fā)布時(shí)間:2021-01-20 14:39:39 來源:億速云 閱讀:313 作者:Leah 欄目:開發(fā)技術(shù)

今天就跟大家聊聊有關(guān)HashTable與Dictionary在C# 中有什么區(qū)別,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。

1. 哈希表(HashTable)簡(jiǎn)述

在.NET Framework中,Hashtable是System.Collections命名空間提供的一個(gè)容器,用于處理和表現(xiàn)類似keyvalue的鍵值對(duì),其中key通??捎脕砜焖俨檎遥瑫r(shí)key是區(qū)分大小寫;value用于存儲(chǔ)對(duì)應(yīng)于key的值。Hashtable中keyvalue鍵值對(duì)均為object類型,所以Hashtable可以支持任何類型的keyvalue鍵值對(duì).

2. 什么情況下使用哈希表

(1)某些數(shù)據(jù)會(huì)被高頻率查詢(2)數(shù)據(jù)量大(3)查詢字段包含字符串類型(4)數(shù)據(jù)類型不唯一

3. 哈希表的使用方法

哈希表需要使用的namespace

using System.Collections;
using System.Collections.Generic;

哈希表的基本操作:

//添加一個(gè)keyvalue鍵值對(duì):
HashtableObject.Add(key,value);
//移除某個(gè)keyvalue鍵值對(duì):
HashtableObject.Remove(key);
//移除所有元素:      
HashtableObject.Clear(); 
// 判斷是否包含特定鍵key:
HashtableObject.Contains(key);

控制臺(tái)程序例子:

using System;
using System.Collections; //file使用Hashtable時(shí),必須引入這個(gè)命名空間
class Program
{
 public static void Main()
 {
   Hashtable ht = new Hashtable(); //創(chuàng)建一個(gè)Hashtable實(shí)例
   ht.Add("北京", "帝都"); //添加keyvalue鍵值對(duì)
   ht.Add("上海", "魔都");
   ht.Add("廣州", "省會(huì)");
   ht.Add("深圳", "特區(qū)");
   string capital = (string)ht["北京"];
   Console.WriteLine(ht.Contains("上海")); //判斷哈希表是否包含特定鍵,其返回值為true或false
   ht.Remove("深圳"); //移除一個(gè)keyvalue鍵值對(duì)
   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);
  }
}

當(dāng)獲取哈希表中數(shù)據(jù)時(shí),如果類型聲明的不對(duì),會(huì)出現(xiàn)InvalidCastException錯(cuò)誤。使用as-statements可以避免該錯(cuò)誤。

using System;
using System.Collections;
using System.IO;
class Program
{
  static void Main()
  {
  Hashtable hashtable = new Hashtable();
  hashtable.Add(100, "西安");
  // 能轉(zhuǎn)換成功
  string value = hashtable[100] as string;
  if (value != null)
  {
    Console.WriteLine(value);
  }
  // 轉(zhuǎn)換失敗,獲取的值為null,但不會(huì)拋出錯(cuò)誤。
  StreamReader reader = hashtable[100] as StreamReader;
  if (reader == null)
  {
     Console.WriteLine("西安不是StreamReader型");
  }
  // 也可以直接獲取object值,再做判斷
  object value2 = hashtable[100];
  if (value2 is string)
  {
    Console.Write("這個(gè)是字符串型: ");
    Console.WriteLine(value2);
  }
  }
}

4. 遍歷哈希表

遍歷哈希表需要用到DictionaryEntry Object,代碼如下:

for(DictionaryEntry de in ht) //ht為一個(gè)Hashtable實(shí)例
{
  Console.WriteLine(de.Key); //de.Key對(duì)應(yīng)于keyvalue鍵值對(duì)key
  Console.WriteLine(de.Value); //de.Key對(duì)應(yīng)于keyvalue鍵值對(duì)value
}

遍歷鍵

foreach (int key in hashtable.Keys)
{
  Console.WriteLine(key);
}

遍歷值

foreach (string value in hashtable.Values)
{
  Console.WriteLine(value);
}

5. 對(duì)哈希表進(jìn)行排序

對(duì)哈希表按key值重新排列的做法:

ArrayList akeys=new ArrayList(ht.Keys); 
akeys.Sort(); //按字母順序進(jìn)行排序
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ù)時(shí)Hashtable快。頻繁調(diào)用數(shù)據(jù)時(shí)Dictionary快。

結(jié)論:

Dictionary<K,V>是泛型的,當(dāng)K或V是值類型時(shí),其速度遠(yuǎn)遠(yuǎn)超過Hashtable。

補(bǔ)充:C# 哈希表Hashtable與字典表Dictionary<K,V>的比較。

一、Hashtable 和 Dictionary <K, V> 類型

1):?jiǎn)尉€程程序中推薦使用 Dictionary, 有泛型優(yōu)勢(shì), 且讀取速度較快, 容量利用更充分.

2):多線程程序中推薦使用 Hashtable, 默認(rèn)的 Hashtable 允許單線程寫入, 多線程讀取, 對(duì) Hashtable 進(jìn)一步調(diào)用 Synchronized()方法可以獲得完全線程安全的類型. 而Dictionary 非線程安全, 必須人為使用 lock 語句進(jìn)行保護(hù), 效率大減.

3):Dictionary 有按插入順序排列數(shù)據(jù)的特性 (注: 但當(dāng)調(diào)用 Remove() 刪除過節(jié)點(diǎn)后順序被打亂), 因此在需要體現(xiàn)順序的情境中使用 Dictionary 能獲得一定方便.

在使用哈希表保存集合元素(一種鍵/值對(duì))時(shí),首先要根據(jù)鍵自動(dòng)計(jì)算哈希代碼,以確定該元素的保存位置,再把元素的值放入相應(yīng)位置所指向的存儲(chǔ)桶中。在查找時(shí),再次通過鍵所對(duì)應(yīng)的哈希代碼到特定存儲(chǔ)桶中搜索,這樣將大大減少為查找一個(gè)元素進(jìn)行比較的次數(shù)。

HashTable中的key/value均為object類型,由包含集合元素的存儲(chǔ)桶組成。存儲(chǔ)桶是 HashTable中各元素的虛擬子組,與大多數(shù)集合中進(jìn)行的搜索和檢索相比,存儲(chǔ)桶可令搜索和檢索更為便捷。每一存儲(chǔ)桶都與一個(gè)哈希代碼關(guān)聯(lián),該哈希代碼是使用哈希函數(shù)生成的并基于該元素的鍵。HashTable的優(yōu)點(diǎn)就在于其索引的方式,速度非??臁H绻匀我忸愋玩I值訪問其中元素會(huì)快于其他集合,特別是當(dāng)數(shù)據(jù)量特別大的時(shí)候,效率差別尤其大。

HashTable的應(yīng)用場(chǎng)合有:做對(duì)象緩存,樹遞歸算法的替代,和各種需提升效率的場(chǎng)合。

二、哈希表Hashtabl

Hastable是哈希表的實(shí)現(xiàn),能根據(jù)關(guān)鍵字取關(guān)鍵值,這key的類型是object, value的類型也是object。

在哈希表中添加一個(gè)key/value鍵值對(duì):HashtableObject.Add(key,value);

在哈希表中去除某個(gè)key/value鍵值對(duì):HashtableObject.Remove(key);

從哈希表中移除所有元素: HashtableObject.Clear();

判斷哈希表是否包含特定鍵key: HashtableObject.Contains(key);

遍歷Hashtable對(duì)象的兩種方法:

由于Hashtable每個(gè)元素都是一個(gè)鍵/值對(duì),因此元素類型既不是鍵的類型,也不是值的類型,而是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)存儲(chǔ)的默認(rèn)類型是object,需要進(jìn)行轉(zhuǎn)換才可以輸出
  Console.WriteLine(de.Key.ToString());
  Console.WriteLine(de.Value.ToString());
}
 
 
//方法二
System.Collections.IDictionaryEnumerator enumerator = myHashtable.GetEnumerator();
 
while (enumerator.MoveNext())
{
  Console.WriteLine(enumerator.Key);    // Hashtable關(guān)健字
  Console.WriteLine(enumerator.Value);   // Hashtable值
}

三、字典Dictionary

Dictionary<Tkey,Tvalue>是Hastbale的泛型實(shí)現(xiàn)。

<span >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 >字典遍歷示例 
 
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/-->//定義一個(gè)<string,int>的Dictionary,讓它的值進(jìn)行添加(也可以用Add方法)
Dictionary<string, int> dic = new Dictionary<string, int>();
 
//添加兩個(gè)鍵為"成績(jī)1","成績(jī)2";并為它們的值賦為0
dic["成績(jī)1"] = 0;
dic["成績(jī)2"] = 0;
 
// 把這兩個(gè)值分別加1
dic["成績(jī)1"]++;
dic["成績(jī)2"]++;

看完上述內(nèi)容,你們對(duì)HashTable與Dictionary在C# 中有什么區(qū)別有進(jìn)一步的了解嗎?如果還想了解更多知識(shí)或者相關(guān)內(nèi)容,請(qǐng)關(guān)注億速云行業(yè)資訊頻道,感謝大家的支持。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI