1. 程式人生 > >C#中的HashSet, HashTable, Dictionary的區別

C#中的HashSet, HashTable, Dictionary的區別

HashSet和Python中的Set差不多,都是為邏輯運算準備的,HashSet不允許資料有重複,且存入的時單值不是鍵值對。
HashTable和Dictionary差不多,但是他們的實現方式時不同的,Dictionary俗稱字典,裡面存放的時鍵值對,即KeyValuePair,且支援泛型,而HashTable國內一般譯為雜湊表,但是在我看來,為了更好表達它的本質,翻譯為散列表比較好,因為HashTable裡面村的key時以雜湊的方式儲存的,但是Dictionary裡面是按順序的方式存的KeyValuePair。

實踐了才能記得住,所以此處以LeetCode第500題為例來說明這一點。

public
string[] FindWords(string[] words) { for(int i=0;i<words.Length;i++) { words[i] = words[i].ToLower(); } string arr1 = "qwertyuiop"; string arr2 = "asdfghjkl"; string arr3 = "zxcvbnm"; HashSet<int
> map1 = new HashSet<int>(); Dictionary<char, int> map2 = new Dictionary<char, int>(); Hashtable map3 =new Hashtable(); for(int i=0;i<arr1.Length;i++) { map1.Add(i); map2.Add(arr1[i], 1); map3.Add(arr1[i], 1
); } for(int i=0; i<arr2.Length;i++) { map1.Add(i); map2.Add(arr2[i], 2); map3.Add(arr2[i], 2); } for(int i=0; i<arr3.Length;i++) { map1.Add(i); map2.Add(arr3[i], 2); map3.Add(arr3[i], 2); } int flag = 0; List<string> lstStr = new List<string>(); for(int i=0; i<words.Length;i++) { flag = 0; for(int j=0;j<words[i].Length;j++) { if(map2[words[i][0]] != map2[words[i][j]]) { flag = 1; break; } } if(flag == 0) lstStr.Add(words[i]); } return lstStr.ToArray(); }

其中map1是HashSet,map2是Dictionary, map3是HashTable,但是若將if判斷中的map2改成map3會怎麼樣呢?看看這一段程式碼

            object a = 1;
            object b = 1;
            Console.WriteLine(a.GetType());
            if(a==b)
            {
                Console.WriteLine("a==b");
            }

結果是a不等於b,為什麼呢,因為他們內容相同但是地址不同,但是將==改為equals的比較就可以了,具體請查閱equals和==的區別(注意這裡略繞哦)。

這裡面的問題在於HashTable總是把所有變數當成Object所以才會出這個問題,而Dictionary型別則是指定key和value的型別。

另外Dictionary資料結構再單執行緒使用會比較快,存放值型別的資料也會比HashTable快,這是因為HashTable對於存入的數無論是值型別還是引用型別都會變成object型別關於這一點,再看一個小例子。

相關推薦

C#HashSet HashTable Dictionary區別

HashSet和Python中的Set差不多,都是為邏輯運算準備的,HashSet不允許資料有重複,且存入的時單值不是鍵值對。 HashTable和Dictionary差不多,但是他們的實現方式時不同的,Dictionary俗稱字典,裡面存放的時鍵值對,即Ke

學習一下C#常用集合和陣列的區別雖然很基礎但感覺很實用

在C#中,當我們想要儲存一組物件的時候,就會想到用陣列,ArrayList,List這三個物件了。那麼這三者到底有什麼樣的區別呢?我們先來了解一下陣列,因為陣列在C#中是最早出現的。 陣列 陣列有很多的優點,比如說陣列在記憶體中是連續儲存的,所以它的索引速度是非常的快,而且

C++的型別轉換以及與C區別

程式設計的時候,型別轉換在某些緊要的關頭是必需品。 C風格的型別轉換,相對C++風格的型別轉換來說,比較粗魯,C風格的型別轉換,能允許任何型別之間進行轉換,在編寫C++程式時是也可以使用的,要進行精確的型別轉換時,這是一個優點。但是,正是這樣的優點,使C風格的型別轉換,在編

C++函數模板顯式具體化顯式實例化:

程序 使用 集合 typename 內容 方法 區分 bsp 代碼 函數模板 形如: template<typename T> //沒有分號 void func(T &a,T &b); 稱為函數模板,其中,template和typename為關

我的女朋友漏電了–論C++的失敗(failure)缺陷(bug)和異常(exception)

c++先做個廣告置入,如果喜歡這篇文章,你可以到 zhaoyan.website/blog 去查看於此類似的C/C++文章。我承認有點標題黨了,不過這真的是一篇寫軟件的文章,所以如果你已經抽出了一張面巾紙,那麽趁早再把它完美的放回去。這篇軟件文章很軟,源代碼不多,而且大部分都是偽代碼。所以很適合所有人看。我特

c++STL 關於mapsetvector的用法

  一、vector vector相當於是一個可以存放一個任意資料型別的一個容器,通過迭代器可以對其進行相應的操作,如下:   1 vector<CString> arrTest; 2 arrTest.push_back(L"你"); 3 arr

c++什麼是引用什麼是指標。

引用就是引用地址,給變數取個小名,這個都可以改變變數的數值。 程式碼: #include <iostream>   using namespace std;   int main () {    // 宣告簡單的變數   &n

C++const與引用指標之間的關係要點

一、const關鍵字 1、有時我們希望定義這樣的一個變數,它的值不能被改變。這時就可以在定義變數時加上const關鍵字。例如 const int bufSize=512; const型別變數可以進行大部分與非const型別變數相同操作,主要的限制就是不可以在const型別的物件上執

JDK7,8,JD9的hashmaphashtableconcurrenthashmap及他們的區別

內容和標題一樣長哦,人家寫了好久的。如無特別指明,內容對應的原始碼是jdk1.7(後面會和1.8對比) 1:hashmap簡介(如下,陣列-連結串列形式) HashMap的儲存結構         圖中,紫色部分即代表雜湊表,也

C/C++ int 轉 stringstring 轉 int 的幾種方法

C int 轉 string sprintf int a = 1; char strDst[256] = {0}; sprintf_s(strDst,256,"%d",a); itoa int

HashMapHashTableConcurrentHashmap區別和原理

HashTable 底層陣列+連結串列實現,無論key還是value都不能為null,執行緒安全,實現執行緒安全的方式是在修改資料時鎖住整個HashTable,效率低,ConcurrentHashMap做了相關優化 初始size為11,擴容:newsize

C++的RVO優化針對返回值為物件時臨時物件的優化

摘要: RVO (return value optimization) 和NRVO (named return value optimization) 是C++在處理一個函式返回類物件並將返回值賦給另一個物件時,為了減少拷貝構造次數以及析構次數而採用的一種編譯器優化技術。 當函式的返回值

C++ 類與物件類的定義類的作用域成員this指標

概要 這篇文章主要內容是關於類與物件,類的定義,類的作用域,類中成員,this指標。寫的比較粗,後期有時間再改。 什麼是類? 對於類,我認為最早的發言人還是亞里士多德。他歸納事物的方法就是這是什麼(屬性)、能幹什麼(方式)、 起個名字(物件名) 、歸類(抽象)

一文讀懂JDK7,8,JD9的HashMapHashTableConcurrentHashMap及他們的區別

內容和標題一樣長哦,人家寫了好久的。如無特別指明,內容對應的原始碼是jdk1.7(後面會和1.8對比) 1:hashmap簡介(如下,陣列-連結串列形式) HashMap的儲存結構       圖中,紫色部分即代表雜湊表,也稱為雜湊陣列(預設陣列大小是16,每對

C++細節 C++的malloc/free new/delete

首先,malloc/free 是函式,new/delete是一個操作符 下面看一下malloc,free,realloc函式原型 (引用自C++ reference) malloc/free ,calloc,realloc malloc void* malloc

C#的抽象方法虛方法介面之間的對比

1.首先來看一看抽象類 抽象類是特殊的類,不能夠被例項化;具有類的其他特性;抽象方法只能聲明於抽象類中,且不包含任何實現 (就是不能有方法體),派生類也就是子類必須對其進行重寫。另外,抽象類可以派生自一個抽象類,可以覆蓋基類的抽象方法也可以不覆蓋,如果不覆蓋,則其派生類必須覆蓋它們。關鍵字就是 abstr

C#的抽象方法虛方法接口之間的對比

rep ace line light brush abs replay size 它的 1.首先來看一看抽象類 抽象類是特殊的類,不能夠被實例化;具有類的其他特性;抽象方法只能聲明於抽象類中,且不包含任何實現 (就是不能有方法體),派生類也就是子類必須對其進行重寫。另外,抽

c#獲取伺服器IP客戶端IP以及Request.ServerVariables詳細說明

客戶端ip: Request.ServerVariables.Get(“Remote_Addr”).ToString(); 客戶端主機名: Request.ServerVariables.Get(“Remote_Host”).ToString();

C#呼叫python指令碼並使用python第三方arcpy模組

前言 1、C#中呼叫python指令碼,一是通過ironpython直接執行python指令碼,二是通過呼叫Process類啟動電腦上的python.exe,執行python指令碼。 前者在使用第三方arcpy模組式,會提示錯誤:No Module Named arcpy,

c++的訪問屬性和繼承方式一些問題的總結

第一:private, public, protected 訪問標號的訪問範圍。 private:只能由1.該類中的函式、2.其友元函式訪問。 不能被任何其他訪問,該類的物件也不能訪問。 prot