Dictionary、KeyValuePair、Hashtable的比较和使用

本文深入探讨了C#中字典(Dictionary)和哈希表(HashTable)的使用方法、特性及性能差异,包括如何高效地遍历、查找和操作键值对,以及在不同场景下的适用建议。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

Dictionary

官方文档:http://msdn.microsoft.com/en-us/library/xfhwa508.aspx

 

而Directory<T,T>是HashTable的泛型模式,用KeyValuePair<T,T>来遍历Directory<T,T>。

 

Dictionary泛型 中的任何键都必须是唯一的。键不能为空引用,但是如果值类型 TValue 为引用类型,该值则可以为空。

Dictionary 调用 Add 方法之前使用 ContainsKey 方法测试某个键是否存在,否则得到一个KeyNotFoundException。

if (!openWith.ContainsKey("ht"))
{
    openWith.Add("ht", "hypertrm.exe");
    Console.WriteLine("Value added for key = \"ht\": {0}",  openWith["ht"]);
}

当程序频繁尝试字典中不存在的键时,使用 TryGetValue 方法来检索值,这种方法是一种更有效的检索值的方法。

string value = "";
if (openWith.TryGetValue("tif", out value))
{
    Console.WriteLine("For key = \"tif\", value = {0}.", value);
}

测试键是否存在的最有效的方法

// The indexer throws an exception if the requested key is not in the dictionary.
try
{
    Console.WriteLine("For key = \"tif\", value = {0}.",    openWith["tif"]);
}
catch (KeyNotFoundException)
{
    Console.WriteLine("Key = \"tif\" is not found.");
}

相关文档:https://msdn.microsoft.com/zh-cn/library/kw5aaea4(v=vs.110).aspx

 

字典集合的两种遍历

Dictionary<string, string> dictionary = new Dictionary<string,string>();

foreach (string dic in dictionary.Keys)
{
    //Key: dic
    //Value: dictionary[dic]
}
foreach (KeyValuePair<string, string> dic in dictionary
{
    //Key: dic.Key
    //Value: dic.Value 
}

KeyValuePair

结构体,定义可设置或检索的键/值对。

性能比自定义结构体查,可阅读:http://www.cnblogs.com/Artemisblog/p/3706054.html

示例

/// <summary>
/// 设置键/值对
/// </summary>
/// <returns></returns>
private KeyValuePair<int, string> SetKeyValuePair()
{
    int intKey = 1;
    string strValue = "My value";
    KeyValuePair<int, string> kvp = new KeyValuePair<int, string>(intKey, strValue);
    return kvp;
}
/// <summary>
/// 获得键/值对
/// </summary>
private void GetKeyValuePairDemo()
{
    KeyValuePair<int, string> kvp = SetKeyValuePair();
    int intKey = kvp.Key;
    string strValue = kvp.Value;
}

 

http://www.cnblogs.com/Artemisblog/p/3706054.html

http://www.cnblogs.com/KTblog/p/4392248.html

 

 

HashTable

描述

用于处理和表现类似keyvalue的键值对,其中key通常可用来快速查找,同时key是区分大小写;value用于存储对应于key的值。Hashtable中keyvalue键值对均为object类型,所以Hashtable可以支持任何类型的keyvalue键值对.

 Hashtable每个元素都是一个存储在 DictionaryEntry 对象中的键/值对。键不能为 空引用,但值可以。

二,哈希表的简单操作

Hashtable hshTable = new Hashtable(); //  创建哈希表
hshTable .Add("Person1",  "zhanghf");  //  往哈希表里添加键值对
hshTable .Clear();  //移除哈希表里所有的键值对
hshTable .Contains("Person1");   //判断哈希表里是否包含该键
string name = (string)hshTable["Person1"].ToString(); //取哈希表里指定键的值
hshTable.Remove("Person1"); //  删除哈希表里指定键的键值对

IDictionaryEnumerator en = hshTable.GetEnumerator();  //  遍历哈希表所有的键,读出相应的值
while (en.MoveNext())
{
     string str = en.Value.ToString(); 
}
// 循环hashtable
foreach (DictionaryEntry de in hshtable) {...}

 

可以使用Dictionary实现的时候,不要用哈希表。使用值类型时,它需要进行封箱和拆箱,耗费内存资源,效率比较低。


 

http://www.cnblogs.com/liuwenjun830/archive/2006/07/28/462182.html【推荐】

http://www.cnblogs.com/yangleiWPF/archive/2010/11/16/1878494.html

http://www.cnblogs.com/gjcn/archive/2008/07/07/1234560.html

 

 

 参考文章:

C#中Dictionary的用法【推荐】

http://jingyan.baidu.com/article/9989c7460ab872f648ecfeed.html

 

C#中键值对类型Hashtable与Dictionary比较和相关用法

http://www.2cto.com/kf/201304/201715.html

Hashtable与Dictionary虽然都是作为键值对的载体,但是采用的是不同的数据结构。就像Java中的ArrayList与LinkList,虽然都是实现了List接口作为集合载体,但其内部结构是不一样的,
ArrayList是通过数组实现的,LinkList是通过对象链表实现的。 由于 Hashtable 和 Dictionary 同时存在, 在使用场景上必然存在选择性, 并不任何时刻都能相互替代. [
1] 单线程程序中推荐使用 Dictionary, 有泛型优势, 且读取速度较快, 容量利用更充分. [2] 多线程程序中推荐使用 Hashtable, 默认的 Hashtable 允许单线程写入, 多线程读取, 对 Hashtable 进一步调用 Synchronized() 方法可以获得完全线程安全的类型.
而 Dictionary 非线程安全, 必须人为使用 lock 语句进行保护, 效率大减. [3] Dictionary 有按插入顺序排列数据的特性 (注: 但当调用 Remove() 删除过节点后顺序被打乱), 因此在需要体现顺序的情境中使用 Dictionary 能获得一定方便. 个人偏向于使用Dictionary,因为其使用泛型,可控性比较强。在一些资料中,很多人也推荐使用Dictionary,其原因主要有 1、Dic是类型安全的,这有助于我们写出更健壮更具可读性的代码,而且省却我们强制转化的麻烦。 2、Dic是泛行的,当K或V是值类型时,其速度远远超过Hashtable。处理对象时不需要进行显式或是隐式转型,进行值类型处理时不需要装箱。所以使用方便一些,
而且效率会高一些(编码效率、运行效率),还不太容易出错。

 

 

 

 

 

### C#Dictionary Map 的区别 在 C# 编程语言中,并没有直接称为 `Map` 的数据结构,通常所说的 `Map` 是指其他编程语言(如 Java)中的 `Map` 接口,其功能 C# 中的 `Dictionary<TKey, TValue>` 类似。因此,在讨论 C# 中的 `Dictionary` 其他类似 `Map` 的结构时,实际上主要比较的是 `Dictionary<TKey, TValue>` 非泛型的 `Hashtable`。 #### 区别 1. **泛型 vs 非泛型** `Dictionary<TKey, TValue>` 是泛型集合类,支持类型安全,能够存储特定类型的键值,避免了运行时类型转换错误[^4]。而 `Hashtable` 是非泛型集合,其键值都是 `Object` 类型,因此在存储或检索值类型时需要进行装箱拆箱操作,影响性能。 2. **线程安全性** `Hashtable` 提供了一些线程安全的实现,适用于多线程环境下的读写操作。然而,这种线程安全是有限的,通常需要额外的同步机制来确保完全的线程安全。相比之下,`Dictionary<TKey, TValue>` 并不是线程安全的,若需在多线程环境中使用,必须通过外部同步机制来保证线程安全。 3. **性能** 对于值类型而言,`Dictionary<TKey, TValue>` 的性能优于 `Hashtable`,因为 `Hashtable` 在处理值类型时需要进行装箱拆箱操作,这会带来额外的开销[^4]。此外,`Dictionary<TKey, TValue>` 内部采用了更高效的算法来管理键值对,从而提高了查找、插入删除的速度。 4. **排序特性** `Dictionary<TKey, TValue>` 保持了键值对的顺序(从 .NET Core 2.0 .NET Standard 2.1 开始),这意味着可以按照插入顺序遍历键值对。而 `Hashtable` 不保证键值对的顺序,遍历时顺序可能会发生变化。 5. **扩展性** `Dictionary<TKey, TValue>` 支持自定义的键比较器,可以通过构造函数传入 `IEqualityComparer<TKey>` 来改变键的相等判断逻辑。这对于某些特殊需求非常有用,例如忽略大小写的字符串键比较。`Hashtable` 同样支持自定义比较器,但其实现方式较为繁琐。 #### 使用场景 - **Dictionary<TKey, TValue>** 当需要一个高效、类型安全的键值对集合,并且不需要线程安全时,应优先选择 `Dictionary<TKey, TValue>`。特别是在处理值类型时,`Dictionary<TKey, TValue>` 能够提供更好的性能。此外,如果需要保持键值对的插入顺序,也可以考虑使用 `Dictionary<TKey, TValue>`。 - **Map(对应 C#Hashtable)** 如果需要一个简单的键值对集合,并且不关心类型安全性性能优化,可以选择 `Hashtable`。尤其在一些遗留代码或者需要兼容旧版本 .NET Framework 的项目中,`Hashtable` 仍然是一个可行的选择。此外,`Hashtable` 在多线程环境下提供了部分线程安全的支持,适合用于简单的并发读取场景。 ```csharp // 示例:创建并使用 Dictionary<TKey, TValue> Dictionary<string, int> dictionary = new Dictionary<string, int>(); dictionary.Add("one", 1); dictionary.Add("two", 2); foreach (KeyValuePair<string, int> kvp in dictionary) { Console.WriteLine($"Key: {kvp.Key}, Value: {kvp.Value}"); } // 示例:创建并使用 Hashtable Hashtable hashtable = new Hashtable(); hashtable.Add("one", 1); hashtable.Add("two", 2); foreach (DictionaryEntry entry in hashtable) { Console.WriteLine($"Key: {entry.Key}, Value: {entry.Value}"); } ``` ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值