先看下面的代碼
using System;
using System.Collections;
namespace NoSortHashtable
{
/// <summary>
/// Summary description for Class1.
/// </summary>
class Class1
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
Hashtable hashTable = new Hashtable();
hashTable.Add("hunan","changsha");
hashTable.Add("beijing","beijing");
hashTable.Add("anhui","hefei");
hashTable.Add("sichuan","chengdu");
foreach(string str in hashTable.Keys)
{
Console.WriteLine(str + " : " + hashTable[str]);
}
}
}
}
列印的結果是:
anhui : hefei
hunan : changsha
sichuan : chengdu
beijing : beijing為何產生這樣的結果? 我查了MSDN後發現----------------------------------------------------------------------------------------------------
Hashtable 對象由包含集合元素的儲存桶組成。儲存桶是 Hashtable 中各元素的虛擬子組,與大多數集合中進行的搜尋和檢索相比,儲存桶可令搜尋和檢索更為便捷。每一儲存桶都與一個雜湊碼關聯,該雜湊碼是使用雜湊函數產生的並基於該元素的鍵。
雜湊函數是基於鍵返回數值雜湊碼的演算法。鍵是正被儲存的對象的某一屬性的值。雜湊函數必須始終為相同的鍵返回相同的雜湊碼。一個雜湊函數能夠為兩個不同的鍵產生相同的雜湊碼,但從雜湊表檢索元素時,為每一唯一鍵產生唯一雜湊碼的雜湊函數將令效能更佳。
在 Hashtable 中用作元素的每一對象必須能夠使用 GetHashCode 方法的實現為其自身產生雜湊碼。但是,還可以通過使用接受 IHashCodeProvider 實現作為參數之一的 Hashtable 建構函式,為 Hashtable 中的所有元素指定一個雜湊函數。
在將一個對象添加到 Hashtable 時,它被儲存在儲存桶中,該儲存桶與匹配該對象的雜湊碼的雜湊碼關聯。在 Hashtable 內搜尋一個值時,將為該值產生雜湊碼,並且搜尋與該雜湊碼關聯的儲存桶。
例如,一個字串的雜湊函數可以採用該字串中每一字元的 ASCII
代碼並它們添加到一起來產生一個雜湊碼。字串“picnic”將具有與字串“basket”的雜湊碼不同的雜湊碼;因此,字串
“picnic”和“basket”將處於不同的儲存桶中。與之相比,“stressed”和“desserts”將具有相同的雜湊碼並將處於相同的存
儲桶中。
Dictionary 類與 Hashtable 類的功能相同。對於實值型別,特定類型(不包括 Object)的 Dictionary 的效能優於 Hashtable,這是因為 Hashtable 的元素屬於 Object 類型,所以在儲存或檢索實值型別時通常發生裝箱和unboxing操作。
----------------------------------------------------------------------------------------------------
產生這個結果的原因就是Hashtable內部的排序機制使然,但我現在就是不想排序,我按什麼順序輸入的,就想它再怎麼給我輸出,怎麼辦? google後發現幾個可以解決的辦法,不過都需要自己寫代碼實現 比如,繼承hashtable,使用不自動排序的arraylist做中間橋using System;
using System.Collections;
namespace NoSortHashtable
{
public class NoSortHashtable : Hashtable
{
private ArrayList keys = new ArrayList();
public NoSortHashtable()
{
}
public override void Add(object key, object value)
{
base.Add (key, value);
keys.Add (key);
}
public override ICollection Keys
{
get
{
return keys;
}
}
public override void Clear()
{
base.Clear ();
keys.Clear ();
}
public override void Remove(object key)
{
base.Remove (key);
keys.Remove (key);
}
public override IDictionaryEnumerator GetEnumerator()
{
return base.GetEnumerator ();
}
}
} 或者只要Compare函數的返回結果不等於0就可以添加相同的Key,這樣可以實現既可以排序,又可以有相同的Key值,可能在某些情況下會用得到。
using System;
using System.Collections;
namespace testSortedList
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
SortedList sl = new SortedList(new MySort()); //不排序
sl.Add(333,333);
sl.Add(111,111);
sl.Add(222,222);
sl.Add(111,112);
PrintList(sl);
Console.ReadLine();
}
private static void PrintList(SortedList sl)
{
for(int i=0;i<sl.Count ;i++)
{
Console.WriteLine("{0}\t{1}",sl.GetKey(i),sl.GetByIndex(i));
}//end for
}//end fn()
}
public class MySort:IComparer
{
#region IComparer 成員
public int Compare(object x, object y)
{
return -1;
//排序
// int iResult = (int)x - (int)y;
// if(iResult == 0) iResult = -1;
// return iResult;
}
#endregion
}
}
另外,System.Collections.Specialized.ListDictionary也是可以完成該要求的,不過。。。
使用單連結清單實現 IDictionary。建議用於通常包含 10 個或 10 個以下項的集合。
最後我測試了使用泛類型的Dictionary<T,T>, 儘管msdn上說hashtable和Dictionary的實現是一樣的,不過同樣的資料,返回的結果卻是不同的,我沒有找到更多的解釋,測試代碼如下
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Collections.Generic;
namespace NoSortHashtable
{
/// <summary>
/// Summary description for Class1.
/// </summary>
public class Class1
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
Hashtable ht = new Hashtable();
ht.Add("hunan","changsha");
ht.Add("beijing","beijing");
ht.Add("anhui","hefei");
ht.Add("sichuan","chengdu");
foreach(string str in ht.Keys)
{
Console.WriteLine(str + " : " + ht[str]);
}
Console.WriteLine("------------------------------------");
Dictionary<String,String> dic = new Dictionary<String,String>();
dic.Add("hunan","changsha");
dic.Add("beijing","beijing");
dic.Add("anhui","hefei");
dic.Add("sichuan","chengdu");
foreach(string str in dic.Keys)
{
Console.WriteLine(str + " : " + dic[str]);
}
Console.WriteLine("------------------------------------");
ListDictionary lsdic = new ListDictionary();
lsdic.Add("hunan","changsha");
lsdic.Add("beijing","beijing");
lsdic.Add("anhui","hefei");
lsdic.Add("sichuan","chengdu");
foreach(string str in lsdic.Keys)
{
Console.WriteLine(str + " : " + lsdic[str]);
}
}
}
}