Nak*_*ary 1348 .net c# vb.net data-structures
在大多数编程语言中,字典比散列表更受欢迎.这背后的原因是什么?
Mic*_*sen 1529
对于它的价值,一个字典是(概念)的哈希表.
如果你的意思是"为什么我们使用Dictionary<TKey, TValue>类而不是Hashtable类?",那么这是一个简单的答案:Dictionary<TKey, TValue>是泛型类型,Hashtable不是.这意味着您可以获得类型安全性Dictionary<TKey, TValue>,因为您无法在其中插入任何随机对象,并且您不必强制转换所取出的值.
有趣的是,Dictionary<TKey, TValue>.NET Framework中的实现是基于Hashtable,正如您可以从其源代码中的注释中看出的那样:
通用词典是从Hashtable的源代码复制而来的
Mar*_*oth 615
Dictionary<<< >>> Hashtable差异:
Synchronized()KeyValuePair<<< >>>枚举项目:DictionaryEntryDictionary/ Hashtable相似之处:
GetHashCode()方法类似的 .NET集合(候选使用而不是Dictionary和Hashtable):
ConcurrentDictionary- 线程安全(可以同时从多个线程安全地访问)HybridDictionary- 优化的性能(少数项目和许多项目)OrderedDictionary- 可以通过int索引访问值(按添加项目的顺序)SortedDictionary- 项目自动排序StringDictionary- 强类型和优化字符串giu*_*ius 177
因为Dictionary是一个泛型类(Dictionary<TKey, TValue>),所以访问它的内容是类型安全的(即你不需要Object像使用a一样进行转换Hashtable).
相比
var customers = new Dictionary<string, Customer>();
...
Customer customer = customers["Ali G"];
Run Code Online (Sandbox Code Playgroud)
至
var customers = new Hashtable();
...
Customer customer = customers["Ali G"] as Customer;
Run Code Online (Sandbox Code Playgroud)
但是,Dictionary在内部实现为哈希表,因此从技术上讲它的工作方式相同.
小智 87
仅供参考:在.NET中,Hashtable线程可以安全地供多个读取器线程和单个写入线程使用,而在Dictionary公共静态成员中是线程安全的,但不保证任何实例成员都是线程安全的.
因此,我们不得不改变所有字典Hashtable.
Mar*_*ell 67
在.NET之间的差异Dictionary<,>,并HashTable主要是前者是一个泛型类型,所以你在静态类型检查(并降低拳击而言仿制药的所有好处,但这不是大如人们往往认为在性能条款 - 虽然拳击有一定的记忆成本.
rix*_*rrr 34
人们说词典与哈希表相同.
这不一定是真的.哈希表是实现字典的一种方法.这是一个典型的,它可能是Dictionary类中.NET中的默认值,但根据定义它不是唯一的一个.
你也可以使用链表或搜索树来实现字典,它只是效率不高(对某些效率指标而言).
Suj*_*jit 21
Collections&Generics对于处理对象组很有用.在.NET中,所有集合对象都在接口之下,接口IEnumerable又具有ArrayList(Index-Value))&HashTable(Key-Value).在.NET framework 2.0之后,ArrayList&HashTable被替换为List&Dictionary.现在,在现在的项目中不再使用Arraylist&HashTable.
来到之间的区别HashTable和Dictionary,Dictionary是通用的,其中如Hastable不通用.我们可以添加任何类型的对象HashTable,但在检索时我们需要将其强制转换为所需的类型.所以,它不是类型安全的.但是dictionary,在声明自己时我们可以指定键和值的类型,因此在检索时不需要进行转换.
我们来看一个例子:
哈希表
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
字典,
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
Alt*_*tel 16
字典:
如果我们试图找到一个不存在的密钥,它会返回/抛出异常.
它比Hashtable更快,因为没有装箱和拆箱.
只有公共静态成员是线程安全的.
Dictionary是一种泛型类型,这意味着我们可以将它与任何数据类型一起使用(创建时,必须指定键和值的数据类型).
例: Dictionary<string, string> <NameOfDictionaryVar> =
new Dictionary<string, string>();
Dictionay是Hashtable的类型安全实现,Keys并且Values是强类型的.
哈希表:
如果我们试图找到一个不存在的密钥,它将返回null.
它比字典慢,因为它需要装箱和拆箱.
Hashtable中的所有成员都是线程安全的,
Hashtable不是通用类型,
Hashtable是松散类型的数据结构,我们可以添加任何类型的键和值.
ale*_*kow 16
使用 MSDN上的C#文章对数据结构的广泛检查表明,冲突解决策略也存在差异 :
Hashtable类使用称为rehashing的技术.
Rehashing的工作原理如下:有一组散列不同的函数,H 1 ... H n,当从散列表中插入或检索项时,最初使用H 1散列函数.如果这导致碰撞,则尝试使用H 2,并且如果需要,则转发到H n.
字典使用称为链接的技术.
通过重新散列,在发生冲突时,重新计算散列,并尝试对应于散列的新槽.然而,通过链接,利用辅助数据结构来保持任何冲突.具体来说,Dictionary中的每个插槽都有一个映射到该存储桶的元素数组.如果发生碰撞,碰撞元素将被添加到桶的列表中.
Oli*_*ver 15
从.NET Framework 3.5开始HashSet<T>,Dictionary<TKey, TValue>如果只需要密钥而没有值,那么它还提供了所有优点.
因此,如果您使用a Dictionary<MyType, object>并始终将值设置null为模拟类型安全哈希表,您应该考虑切换到HashSet<T>.
fle*_*esh 13
这Hashtable是一个松散类型的数据结构,因此您可以将任何类型的键和值添加到Hashtable.该Dictionary班是一种安全的Hashtable实现和键和值是强类型.创建Dictionary实例时,必须为键和值指定数据类型.
小智 11
请注意,MSDN说:"Dictionary <(Of <(TKey,TValue>)>)类实现为哈希表 ",而不是"Dictionary <(Of <(TKey,TValue>)>)类实现为HashTable "
Dictionary不是作为HashTable实现的,而是按照哈希表的概念实现的.由于使用了Generics,实现与HashTable类无关,尽管内部Microsoft可能使用了相同的代码并用TKey和TValue替换了Object类型的符号.
在.NET 1.0中,Generics不存在; 这是HashTable和ArrayList最初开始的地方.
哈希表:
键/值将在存储到堆中时转换为对象(装箱)类型.
在从堆读取时,需要将键/值转换为所需的类型.
这些操作非常昂贵.我们需要尽可能避免装箱/拆箱.
字典: HashTable的通用变体.
没有拳击/拆箱.无需转换.
Hashtable对象由包含集合元素的存储桶组成.存储桶是Hashtable中虚拟的元素子组,与大多数集合相比,它使搜索和检索更容易,更快捷.
Dictionary类与Hashtable类具有相同的功能.特定类型的字典(除了Object)具有比值类型的Hashtable更好的性能,因为Hashtable的元素是Object类型,因此,如果存储或检索值类型,通常会发生装箱和取消装箱.
进一步阅读:Hashtable和字典集合类型
另一个重要的区别是Hashtable是线程安全的.Hashtable内置多个读取器/单个写入器(MR/SW)线程安全性,这意味着Hashtable允许一个编写器与多个读取器一起使用而无需锁定.
在Dictionary的情况下,没有线程安全; 如果您需要线程安全,则必须实现自己的同步.
进一步阐述:
Hashtable通过
Synchronized属性提供一些线程安全性,它返回集合周围的线程安全包装器.包装器通过在每次添加或删除操作时锁定整个集合来工作.因此,尝试访问集合的每个线程必须等待轮到一个锁.这不可扩展,可能会导致大型集合的性能显着下降.此外,该设计并未完全免受竞争条件的影响..NET Framework 2.0集合类
List<T>, Dictionary<TKey, TValue>等不提供任何线程同步; 用户代码必须在多个线程上同时添加或删除项目时提供所有同步
如果您需要类型安全性以及线程安全性,请在.NET Framework中使用并发集合类.进一步阅读这里.
另一个区别是,当我们在Dictionary中添加多个条目时,将保留添加条目的顺序.当我们从Dictionary中检索项目时,我们将按照插入它们的相同顺序获取记录.而Hashtable不保留插入顺序.
Dictionary<> 是一种通用类型,所以它的类型安全.
您可以在HashTable中插入任何值类型,这有时会引发异常.但是Dictionary<int>只接受整数值,同样Dictionary<string>只接受字符串.
因此,最好使用Dictionary<>而不是HashTable.