在大多数编程语言中,字典比哈希表更受欢迎。这背后的原因是什么?
当前回答
自.NET Framework 3.5以来,还有一个HashSet<T>,它提供了字典<TKey,TValue>的所有优点,如果您只需要键而不需要值。
因此,如果您使用Dictionary<MyType,object>并始终将值设置为null以模拟类型安全哈希表,您可能应该考虑切换到HashSet<T>。
其他回答
在.NET中,Dictionary<,>和HashTable之间的区别主要在于前者是一种泛型类型,因此在静态类型检查方面可以获得泛型的所有好处(以及减少装箱,但这并不像人们在性能方面所想的那么大-尽管装箱会有一定的内存成本)。
MSDN上的《使用C#对数据结构进行广泛检查》一文指出,冲突解决策略也存在差异:
Hashtable类使用一种称为rehashing的技术。
Rehashing的工作原理如下:有一组哈希不同的函数,H1。。。Hn,并且当从哈希中插入或检索项时表中,最初使用H1哈希函数。如果这导致如果需要,则尝试H2,然后继续到Hn。
字典使用了一种称为链接的技术。
通过重新散列,在发生冲突时,将重新计算哈希,并尝试与哈希对应的新槽。然而,通过链接,使用辅助数据结构来保存任何碰撞。具体来说,字典中的每个插槽都有一个数组映射到该存储桶的元素。如果发生碰撞冲突元素被添加到桶的列表中。
自.NET Framework 3.5以来,还有一个HashSet<T>,它提供了字典<TKey,TValue>的所有优点,如果您只需要键而不需要值。
因此,如果您使用Dictionary<MyType,object>并始终将值设置为null以模拟类型安全哈希表,您可能应该考虑切换到HashSet<T>。
集合和泛型对于处理一组对象非常有用。在.NET中,所有集合对象都位于接口IEnumerable下,该接口又具有ArrayList(索引值)和HashTable(键值)。在.NET framework 2.0之后,ArrayList和HashTable被List和Dictionary取代。现在,Arraylist和HashTable在现在的项目中不再使用。
谈到HashTable和Dictionary之间的区别,Dictionary是泛型的,而Hastable不是泛型的。我们可以向HashTable中添加任何类型的对象,但在检索时需要将其转换为所需的类型。因此,它不是类型安全的。但对于字典,在声明自身时,我们可以指定键和值的类型,因此在检索时不需要强制转换。
我们来看一个示例:
散列表
class HashTableProgram
{
static void Main(string[] args)
{
Hashtable ht = new Hashtable();
ht.Add(1, "One");
ht.Add(2, "Two");
ht.Add(3, "Three");
foreach (DictionaryEntry de in ht)
{
int Key = (int)de.Key; //Casting
string value = de.Value.ToString(); //Casting
Console.WriteLine(Key + " " + value);
}
}
}
词典
class DictionaryProgram
{
static void Main(string[] args)
{
Dictionary<int, string> dt = new Dictionary<int, string>();
dt.Add(1, "One");
dt.Add(2, "Two");
dt.Add(3, "Three");
foreach (KeyValuePair<int, String> kv in dt)
{
Console.WriteLine(kv.Key + " " + kv.Value);
}
}
}
从概念上讲,字典是一个哈希表。
如果你的意思是“为什么我们使用Dictionary<TKey,TValue>类而不是Hashtable类?”,那么答案很简单:Dictionary>TKey,TValue>是泛型类型,Hashtable不是。这意味着你可以通过Dictionary<TKey,TValue>获得类型安全性,因为你不能在其中插入任何随机对象,也不必强制转换你取出的值。
有趣的是,.NET Framework中的Dictionary<TKey,TValue>实现是基于Hashtable的,您可以从其源代码中的注释中看出:
通用字典已从Hashtable的源复制
来源
推荐文章
- net HttpClient。如何POST字符串值?
- 我如何使一个方法的返回类型泛型?
- 何时处理CancellationTokenSource?
- 如何在Java中打印二叉树图?
- 如何获取正在执行的程序集版本?
- AutoMapper vs valueinjector
- 为什么控制台不。Writeline,控制台。在Visual Studio Express中编写工作?
- 什么是.NET程序集?
- 字符串不能识别为有效的日期时间“格式dd/MM/yyyy”
- 函数应该返回空对象还是空对象?
- 如何转换日期时间?将日期时间
- 如何在c#中连接列表?
- 在c#中引用类型变量的“ref”的用途是什么?
- 防止在ASP中缓存。NET MVC中使用属性的特定操作
- 转换为值类型'Int32'失败,因为物化值为空