字典Dictionary
在 C# 中使用 Dictionary<TKey, TValue>
时,需要注意以下几点:
键的唯一性:
- 字典中的每个键必须是唯一的。如果尝试添加一个已经存在的键,会抛出
ArgumentException
。1
2
3var dict = new Dictionary<int, string>();
dict.Add(1, "value1");
dict.Add(1, "value2"); // 抛出 ArgumentException
- 字典中的每个键必须是唯一的。如果尝试添加一个已经存在的键,会抛出
键的哈希码和相等性:
- 键的类型必须正确实现
GetHashCode
和Equals
方法。如果键的类型是一个自定义类,确保正确实现这两个方法,以便字典能够正确区分键。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15public class Key
{
public int Id { get; set; }
public override bool Equals(object obj)
{
if (obj is Key key)
return Id == key.Id;
return false;
}
public override int GetHashCode()
{
return Id.GetHashCode();
}
}
- 键的类型必须正确实现
性能考虑:
- 字典查找、添加和删除操作的时间复杂度平均为 O(1),但在哈希冲突较多的情况下可能退化到 O(n)。选择合适的键类型和哈希函数以减少冲突。
访问不存在的键:
- 直接访问一个不存在的键会抛出
KeyNotFoundException
。可以使用TryGetValue
方法避免异常。1
2
3
4
5
6
7
8if (dict.TryGetValue(2, out var value))
{
Console.WriteLine(value);
}
else
{
Console.WriteLine("Key not found");
}
- 直接访问一个不存在的键会抛出
初始化容量:
- 如果知道字典的大致大小,可以在初始化时指定容量,减少扩容带来的性能开销。
1
var dict = new Dictionary<int, string>(capacity: 100);
- 如果知道字典的大致大小,可以在初始化时指定容量,减少扩容带来的性能开销。
线程安全:
Dictionary<TKey, TValue>
本身不是线程安全的。如果在多线程环境中使用,请使用ConcurrentDictionary<TKey, TValue>
或手动实现同步机制。
迭代和修改:
- 在迭代字典时修改字典会抛出
InvalidOperationException
。如果需要修改,可以先收集要修改的键值对,然后在迭代完成后再进行修改。1
2
3
4
5
6
7foreach (var key in dict.Keys.ToList())
{
if (key == 1)
{
dict[key] = "newValue";
}
}
- 在迭代字典时修改字典会抛出
序列化:
- 字典可以被序列化,但要确保键和值的类型都支持序列化。常用的 JSON 序列化库如
JsonConvert
和System.Text.Json
都支持字典。1
2var json = JsonConvert.SerializeObject(dict);
var deserializedDict = JsonConvert.DeserializeObject<Dictionary<int, string>>(json);
- 字典可以被序列化,但要确保键和值的类型都支持序列化。常用的 JSON 序列化库如
示例代码
这段示例代码展示了如何正确使用字典以及注意事项。
1 |
|