Dictionary集合 #
一、Dictionary概述 #
Dictionary<K,V>是键值对集合,通过键快速查找值。
1.1 特点 #
- 键唯一
- 高效查找O(1)
- 键值对存储
- 实现IDictionary接口
1.2 创建Dictionary #
csharp
var dict1 = new Dictionary<string, int>();
var dict2 = new Dictionary<string, int>(100);
var dict3 = new Dictionary<string, int>
{
["张三"] = 85,
["李四"] = 92,
["王五"] = 78
};
var dict4 = new Dictionary<string, int>
{
{ "张三", 85 },
{ "李四", 92 }
};
二、添加元素 #
2.1 索引器添加 #
csharp
var scores = new Dictionary<string, int>();
scores["张三"] = 85;
scores["李四"] = 92;
scores["张三"] = 90;
2.2 Add方法 #
csharp
var scores = new Dictionary<string, int>();
scores.Add("张三", 85);
scores.Add("李四", 92);
try
{
scores.Add("张三", 100);
}
catch (ArgumentException ex)
{
Console.WriteLine($"键已存在:{ex.Message}");
}
2.3 TryAdd方法 #
csharp
var scores = new Dictionary<string, int>();
bool added1 = scores.TryAdd("张三", 85);
bool added2 = scores.TryAdd("张三", 100);
三、访问元素 #
3.1 索引器访问 #
csharp
var scores = new Dictionary<string, int>
{
["张三"] = 85,
["李四"] = 92
};
int score = scores["张三"];
try
{
int notFound = scores["王五"];
}
catch (KeyNotFoundException ex)
{
Console.WriteLine($"键不存在:{ex.Message}");
}
3.2 TryGetValue方法 #
csharp
var scores = new Dictionary<string, int>
{
["张三"] = 85,
["李四"] = 92
};
if (scores.TryGetValue("张三", out int score))
{
Console.WriteLine($"张三的分数:{score}");
}
if (scores.TryGetValue("王五", out int notFound))
{
Console.WriteLine($"王五的分数:{notFound}");
}
else
{
Console.WriteLine("王五不存在");
}
3.3 GetValueOrDefault #
csharp
var scores = new Dictionary<string, int>
{
["张三"] = 85
};
int score1 = scores.GetValueOrDefault("张三");
int score2 = scores.GetValueOrDefault("王五");
int score3 = scores.GetValueOrDefault("王五", 0);
四、删除元素 #
4.1 Remove方法 #
csharp
var scores = new Dictionary<string, int>
{
["张三"] = 85,
["李四"] = 92,
["王五"] = 78
};
bool removed1 = scores.Remove("张三");
bool removed2 = scores.Remove("不存在");
4.2 Remove方法(带值返回) #
csharp
var scores = new Dictionary<string, int>
{
["张三"] = 85
};
if (scores.Remove("张三", out int removedScore))
{
Console.WriteLine($"已删除:{removedScore}");
}
4.3 Clear方法 #
csharp
var scores = new Dictionary<string, int>
{
["张三"] = 85,
["李四"] = 92
};
scores.Clear();
五、查找与判断 #
5.1 ContainsKey方法 #
csharp
var scores = new Dictionary<string, int>
{
["张三"] = 85,
["李四"] = 92
};
bool hasZhangSan = scores.ContainsKey("张三");
bool hasWangWu = scores.ContainsKey("王五");
5.2 ContainsValue方法 #
csharp
var scores = new Dictionary<string, int>
{
["张三"] = 85,
["李四"] = 92
};
bool has85 = scores.ContainsValue(85);
bool has100 = scores.ContainsValue(100);
5.3 Count属性 #
csharp
var scores = new Dictionary<string, int>
{
["张三"] = 85,
["李四"] = 92
};
int count = scores.Count;
int countAbove80 = scores.Count(kvp => kvp.Value > 80);
六、遍历 #
6.1 遍历键值对 #
csharp
var scores = new Dictionary<string, int>
{
["张三"] = 85,
["李四"] = 92,
["王五"] = 78
};
foreach (var kvp in scores)
{
Console.WriteLine($"{kvp.Key}: {kvp.Value}");
}
6.2 遍历键 #
csharp
var scores = new Dictionary<string, int>
{
["张三"] = 85,
["李四"] = 92
};
foreach (var key in scores.Keys)
{
Console.WriteLine(key);
}
6.3 遍历值 #
csharp
var scores = new Dictionary<string, int>
{
["张三"] = 85,
["李四"] = 92
};
foreach (var value in scores.Values)
{
Console.WriteLine(value);
}
七、更新元素 #
7.1 索引器更新 #
csharp
var scores = new Dictionary<string, int>
{
["张三"] = 85
};
scores["张三"] = 90;
7.2 批量更新 #
csharp
var scores = new Dictionary<string, int>
{
["张三"] = 85,
["李四"] = 92
};
var newScores = new Dictionary<string, int>
{
["张三"] = 90,
["王五"] = 78
};
foreach (var kvp in newScores)
{
scores[kvp.Key] = kvp.Value;
}
八、实战示例 #
8.1 缓存实现 #
csharp
public class Cache<TKey, TValue>
{
private readonly Dictionary<TKey, TValue> _cache = new();
private readonly TimeSpan _expiration;
private readonly Dictionary<TKey, DateTime> _timestamps = new();
public Cache(TimeSpan expiration)
{
_expiration = expiration;
}
public bool TryGet(TKey key, out TValue value)
{
if (_cache.TryGetValue(key, out value))
{
if (DateTime.Now - _timestamps[key] < _expiration)
{
return true;
}
Remove(key);
}
return false;
}
public void Set(TKey key, TValue value)
{
_cache[key] = value;
_timestamps[key] = DateTime.Now;
}
public void Remove(TKey key)
{
_cache.Remove(key);
_timestamps.Remove(key);
}
public void Clear()
{
_cache.Clear();
_timestamps.Clear();
}
}
8.2 分组统计 #
csharp
public static Dictionary<TKey, int> CountBy<TSource, TKey>(
IEnumerable<TSource> source,
Func<TSource, TKey> keySelector)
{
var result = new Dictionary<TKey, int>();
foreach (var item in source)
{
var key = keySelector(item);
if (!result.ContainsKey(key))
{
result[key] = 0;
}
result[key]++;
}
return result;
}
var words = new[] { "apple", "banana", "apple", "cherry", "banana", "apple" };
var counts = CountBy(words, w => w);
8.3 双向字典 #
csharp
public class BiDictionary<TKey, TValue>
{
private readonly Dictionary<TKey, TValue> _forward = new();
private readonly Dictionary<TValue, TKey> _reverse = new();
public void Add(TKey key, TValue value)
{
if (_forward.ContainsKey(key) || _reverse.ContainsKey(value))
throw new ArgumentException("键或值已存在");
_forward[key] = value;
_reverse[value] = key;
}
public bool TryGetByKey(TKey key, out TValue value)
=> _forward.TryGetValue(key, out value);
public bool TryGetByValue(TValue value, out TKey key)
=> _reverse.TryGetValue(value, out key);
public bool RemoveByKey(TKey key)
{
if (_forward.TryGetValue(key, out var value))
{
_forward.Remove(key);
_reverse.Remove(value);
return true;
}
return false;
}
}
九、总结 #
Dictionary要点:
| 操作 | 方法 |
|---|---|
| 添加 | Add, TryAdd, 索引器 |
| 访问 | 索引器, TryGetValue |
| 删除 | Remove, Clear |
| 查找 | ContainsKey, ContainsValue |
| 遍历 | Keys, Values, KeyValuePair |
下一步,让我们学习队列与栈!
最后更新:2026-03-26