hashtable里存的对象全部是object类型 ,所有对象存进去都被转成object类型,读取出来每次都需要转换类型,hashtable对存入的类型没有限制 , 因此在读取转换类型时容易出错,
dictionary只能存入定义时指定的类型,而且不像hashtable会把类型转换成object,存取起来比前者方便,效率更高,因为不需要转换类型,所以不会出现hashtable里的转换类型错误而报出程序异常.
简单点说在 hashtable所有的对象基于HASH算法管理,但它是无类型信息的都只是一种类型:object,所以你可能需要进行一些类型转换的操作,即浪费时间又有可能出错。而且对于int,float这些值类型还需要进行装箱等操作,非常耗时。
对于Dict <TKey,TValue>是由CLR支持泛型操作,速度快,没有类型转换操作,即完全是类型安全的。
由于 Hashtable 和 Dictionary 同时存在, 在使用场景上必然存在选择性, 并不任何时刻都能相互替代.
[1] 单线程程序中推荐使用 Dictionary, 有泛型优势, 且读取速度较快, 容量利用更充分.
[2] 多线程程序中推荐使用 Hashtable, 默认的 Hashtable 允许单线程写入, 多线程读取, 对 Hashtable 进一步调用 Synchronized() 方法可以获得完全线程安全的类型. 而 Dictionary 非线程安全, 必须人为使用 lock 语句进行保护, 效率大减.
[3] Dictionary 有按插入顺序排列数据的特性 (注: 但当调用 Remove() 删除过节点后顺序被打乱), 因此在需要体现顺序的情境中使用 Dictionary 能获得一定方便.
基本上是Dictionary 性能高些。
下面是有人做的测试:摘自:http://hi.baidu.com/tpasp/blog/item/0b34535195cbee6b85352445.html
using System;
using System.Collections;
{
/// <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("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
----------------------------------------------------------------------------------------------------
Hashtable 对象由包含集合元素的存储桶组成。存储桶是 Hashtable 中各元素的虚拟子组,与大多数集合中进行的搜索和检索相比,存储桶可令搜索和检索更为便捷。每一存储桶都与一个哈希代码关联,该哈希代码是使用哈希函数生成的并基于该元素的键。
google后发现几个可以解决的办法,不过都需要自己写代码实现
比如,继承hashtable,使用不自动排序的arraylist做中间桥
using System;
using System.Collections;
{
public class NoSortHashtable : Hashtable
{
private ArrayList keys = new ArrayList();
{
}
{
base.Add (key, value);
keys.Add (key);
}
{
get
{
return keys;
}
}
{
base.Clear ();
keys.Clear ();
}
{
base.Remove (key);
keys.Remove (key);
}
public override IDictionaryEnumerator GetEnumerator()
{
return base.GetEnumerator ();
}
}
或者
只要Compare函数的返回结果不等于0就可以添加相同的Key,这样可以实现既可以排序,又可以有相同的Key值,可能在某些情况下会用得到。
using System;
using System.Collections;
{
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);
}
{
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
}
using System.Collections;
using System.Collections.Specialized;
using System.Collections.Generic;
{
/// <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]);
}
}
}
}
浙公网安备 33010602011771号