在C#中,Dictionary<TKey, TValue>
是一个泛型集合类,用于存储键值对(key-value pairs)。它提供了快速的查找、插入和删除操作,适合需要根据键快速查找值的场景。以下是 Dictionary
的基本用法和常见操作:
1. 创建字典
使用 Dictionary<TKey, TValue>
类创建字典,其中 TKey
是键的类型,TValue
是值的类型。
// 创建一个键为 string,值为 int 的字典
Dictionary<string, int> ages = new Dictionary<string, int>();
2. 添加键值对
使用 Add
方法或索引器向字典中添加键值对。
// 使用 Add 方法添加
ages.Add("Alice", 30);
ages.Add("Bob", 25);
// 使用索引器添加(如果键已存在,会覆盖值)
ages["Charlie"] = 35;
3. 访问值
通过键访问字典中的值。
// 使用索引器访问
int aliceAge = ages["Alice"];
Console.WriteLine($"Alice's age: {aliceAge}");
// 使用 TryGetValue 安全访问(避免键不存在时抛出异常)
if (ages.TryGetValue("Bob", out int bobAge))
{
Console.WriteLine($"Bob's age: {bobAge}");
}
else
{
Console.WriteLine("Bob's age not found.");
}
4. 修改值
通过键修改字典中的值。
// 修改 Alice 的年龄
ages["Alice"] = 31;
Console.WriteLine($"Alice's new age: {ages["Alice"]}");
5. 删除键值对
使用 Remove
方法删除指定键的键值对。
// 删除键为 "Bob" 的键值对
ages.Remove("Bob");
// 检查是否删除成功
if (!ages.ContainsKey("Bob"))
{
Console.WriteLine("Bob's age has been removed.");
}
6. 检查键或值是否存在
使用 ContainsKey
或 ContainsValue
方法检查字典中是否包含指定的键或值。
// 检查键是否存在
if (ages.ContainsKey("Alice"))
{
Console.WriteLine("Alice is in the dictionary.");
}
// 检查值是否存在
if (ages.ContainsValue(35))
{
Console.WriteLine("Someone is 35 years old.");
}
7. 遍历字典
使用 foreach
循环遍历字典中的键值对。
foreach (var kvp in ages)
{
Console.WriteLine($"{kvp.Key}: {kvp.Value}");
}
// 单独遍历键或值
foreach (var key in ages.Keys)
{
Console.WriteLine($"Key: {key}");
}
foreach (var value in ages.Values)
{
Console.WriteLine($"Value: {value}");
}
8. 清空字典
使用 Clear
方法清空字典中的所有键值对。
ages.Clear();
Console.WriteLine($"Dictionary count after clearing: {ages.Count}");
9. 获取字典的大小
使用 Count
属性获取字典中键值对的数量。
Console.WriteLine($"Number of entries in the dictionary: {ages.Count}");
10. 初始化字典
可以在创建字典时直接初始化键值对。
Dictionary<string, int> ages = new Dictionary<string, int>
{
{ "Alice", 30 },
{ "Bob", 25 },
{ "Charlie", 35 }
};
11. 处理键冲突
如果尝试添加一个已经存在的键,Add
方法会抛出 ArgumentException
。可以使用 ContainsKey
方法检查键是否存在,或者使用索引器直接赋值。
if (!ages.ContainsKey("Alice"))
{
ages.Add("Alice", 30);
}
else
{
Console.WriteLine("Alice already exists in the dictionary.");
}
12. 字典的默认值
如果尝试访问不存在的键,索引器会抛出 KeyNotFoundException
。可以使用 TryGetValue
方法避免异常。
if (ages.TryGetValue("David", out int davidAge))
{
Console.WriteLine($"David's age: {davidAge}");
}
else
{
Console.WriteLine("David's age not found.");
}
13. 使用自定义类型作为键
如果使用自定义类型作为键,需要确保该类型正确实现了 Equals
和 GetHashCode
方法,以便字典能够正确比较和查找键。
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public override bool Equals(object obj)
{
if (obj is Person other)
{
return Name == other.Name && Age == other.Age;
}
return false;
}
public override int GetHashCode()
{
return Name.GetHashCode() ^ Age.GetHashCode();
}
}
// 使用自定义类型作为键
Dictionary<Person, string> personDescriptions = new Dictionary<Person, string>
{
{ new Person { Name = "Alice", Age = 30 }, "Software Engineer" },
{ new Person { Name = "Bob", Age = 25 }, "Data Scientist" }
};
14. 字典的性能
-
查找:
Dictionary
的查找操作是 O(1) 时间复杂度,因为它是基于哈希表实现的。 -
插入和删除:插入和删除操作的平均时间复杂度也是 O(1)。
-
内存开销:由于哈希表的实现,
Dictionary
会占用较多的内存。
15. 完整示例
以下是一个完整的示例,展示了字典的常见操作:
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
// 创建并初始化字典
Dictionary<string, int> ages = new Dictionary<string, int>
{
{ "Alice", 30 },
{ "Bob", 25 },
{ "Charlie", 35 }
};
// 添加新键值对
ages["David"] = 28;
// 修改值
ages["Alice"] = 31;
// 删除键值对
ages.Remove("Bob");
// 遍历字典
foreach (var kvp in ages)
{
Console.WriteLine($"{kvp.Key}: {kvp.Value}");
}
// 检查键是否存在
if (ages.ContainsKey("Charlie"))
{
Console.WriteLine("Charlie is in the dictionary.");
}
// 获取字典大小
Console.WriteLine($"Number of entries: {ages.Count}");
}
}