要了解C#中Hashtable Dictionary的使用我们先来看一个例子! using System; using SystemCollections; namespace NoSortHashtable { /// <summary> /// Summary description for Class /// </summary> class Class { /// <summary> /// The main entry point for the application /// </summary> [STAThread] static void Main(string[] args) { Hashtable hashTable = new Hashtable(); hashTableAdd(\hunan\\changsha\); hashTableAdd(\beijing\\beijing\); hashTableAdd(\anhui\\hefei\); hashTableAdd(\sichuan\\chengdu\); foreach(string str in hashTableKeys) { ConsoleWriteLine(str + \ : \ + hashTable[str]); } } } } 打印的结果是 anhui : hefei hunan : changsha sichuan : chengdu beijing : beijing 为何产生这样的结果? 我查了MSDN后发现
Hashtable 对象由包含集合元素的存储桶组成存储桶是 Hashtable 中各元素的虚拟子组与大多数集合中进行的搜索和检索相比存储桶可令搜索和检索更为便捷每一存储桶都与一个哈希代码关联该哈希代码是使用哈希函数生成的并基于该元素的键 [Page] 哈希函数是基于键返回数值哈希代码的算法键是正被存储的对象的某一属性的值哈希函数必须始终为相同的键返回相同的哈希代码一个哈希函数能够为两个不同的键生成相同的哈希代码但从哈希表检索元素时为每一唯一键生成唯一哈希代码的哈希函数将令性能更佳 在 Hashtable 中用作元素的每一对象必须能够使用 GetHashCode 方法的实现为其自身生成哈希代码但是还可以通过使用接受 IHashCodeProvider 实现作为参数之一的 Hashtable 构造函数为 Hashtable 中的所有元素指定一个哈希函数 在将一个对象添加到 Hashtable 时它被存储在存储桶中该存储桶与匹配该对象的哈希代码的哈希代码关联在 Hashtable 内搜索一个值时将为该值生成哈希代码并且搜索与该哈希代码关联的存储桶 例如一个字符串的哈希函数可以采用该字符串中每一字符的 ASCII 代码并它们添加到一起来生成一个哈希代码字符串picnic将具有与字符串basket的哈希代码不同的哈希代码因此字符串picnic和basket将处于不同的存储桶中与之相比stressed和desserts将具有相同的哈希代码并将处于相同的存储桶中 Dictionary 类与 Hashtable 类的功能相同对于值类型特定类型(不包括 Object)的 Dictionary 的性能优于 Hashtable这是因为 Hashtable 的元素属于 Object 类型所以在存储或检索值类型时通常发生装箱和取消装箱操作中国自学编程网
产生这个结果的原因就是Hashtable内部的排序机制使然但我现在就是不想排序我按什么顺序输入的就想它再怎么给我输出怎么办? google后发现几个可以解决的办法不过都需要自己写代码实现 比如继承hashtable使用不自动排序的arraylist做中间桥 using System; using SystemCollections; namespace NoSortHashtable { public class NoSortHashtable : Hashtable { private ArrayList keys = new ArrayList(); public NoSortHashtable() { } public override void Add(object key object value) { baseAdd (key value); keysAdd (key); [Page] } public override ICollection Keys { get { return keys; } } public override void Clear() { baseClear (); keysClear (); } public override void Remove(object key) { baseRemove (key); keysRemove (key); } public override IDictionaryEnumerator GetEnumerator() { return baseGetEnumerator (); } } } 或者 只要Compare函数的返回结果不等于就可以添加相同的Key这样可以实现既可以排序又可以有相同的Key值可能在某些情况下会用得到 using System; using SystemCollections; namespace testSortedList { class Class { [STAThread] static void Main(string[] args) { SortedList sl = new SortedList(new MySort()); //不排序 [Page] slAdd(); slAdd(); slAdd(); slAdd(); PrintList(sl); ConsoleReadLine(); } private static void PrintList(SortedList sl) { for(int i=;i<slCount ;i++) { ConsoleWriteLine(\{}\\t{}\slGetKey(i)slGetByIndex(i)); }//end for }//end fn() } public class MySort:IComparer { #region IComparer 成员 public int Compare(object x object y) { return ; //排序 // int iResult = (int)x (int)y; // if(iResult == ) iResult = ; // return iResult; } #endregion } } 使用单链接列表实现 IDictionary建议用于通常包含 个或 个以下项的集合 最后我测试了使用泛类型的Dictionary<TT> 尽管msdn上说hashtable和Dictionary的实现是一样的不过同样的数据返回的结果却是不同的我没有找到更多的解释测试代码如下 [Page] using System; using SystemCollections; using SystemCollectionsSpecialized; using SystemCollectionsGeneric; namespace NoSortHashtable { /// <summary> /// Summary description for Class /// </summary> public class Class { /// <summary> /// The main entry point for the application /// </summary> [STAThread] static void Main(string[] args) { Hashtable ht = new Hashtable(); htAdd(\hunan\\changsha\); htAdd(\beijing\\beijing\); htAdd(\anhui\\hefei\); htAdd(\sichuan\\chengdu\); foreach(string str in htKeys) { ConsoleWriteLine(str + \ : \ + ht[str]); } ConsoleWriteLine(\\); Dictionary<StringString> dic = new Dictionary<StringString>(); dicAdd(\hunan\\changsha\); [Page] dicAdd(\beijing\\beijing\); dicAdd(\anhui\\hefei\); dicAdd(\sichuan\\chengdu\); foreach(string str in dicKeys) { ConsoleWriteLine(str + \ : \ + dic[str]); } ConsoleWriteLine(\\); ListDictionary lsdic = new ListDictionary(); lsdicAdd(\hunan\\changsha\); lsdicAdd(\beijing\\beijing\); lsdicAdd(\anhui\\hefei\); lsdicAdd(\sichuan\\chengdu\); foreach(string str in lsdicKeys) { ConsoleWriteLine(str + \ : \ + lsdic[str]); } } } } |