字典的基本使用
添加
Dictionary<string, int> dic_test = new Dictionary<string, int>();
dic_test.Add("Ada",33);
dic_test["Alice"] = 30;
//添加已经在字典中已经存在的键,会有异常
//eg: dic_test.Add("Ada", 24);
//不存在Ada键,则添加成功,返回true,否则不修改,并返回false
dic_test.TryAdd("Ada", 38);
访问
dic_test["Ada"];
若键不存在,会抛出异常
不抛出异常处理方法
//bobAge访问范围与同级
if(dic_test.TryGetValue("Ada", out int bobAge)) {
Console.WriteLine($"Ada的年龄是:{bobAge}");
}
else {
Console.WriteLine("未找到Ada键的值");
}
Console.WriteLine($"Ada的年龄是:{bobAge}");
删除
Console.WriteLine(dic_test.Romove("Ada"));
Console.WriteLine(dic_test.Romove("Ada",out int CarlAge));//删除成功返回true
ContainsKey和ContainsValue方法
if(dic_test.ContainsKey("Ada"))
Console.WriteLine("包含Ada键");
if(dic_test.ContainsValue(18))
Console.WriteLine("包含值 18");
字典的使用场景
- 数据索引
- 统计频次
- 缓存数据
Dictionary的实现原理
关键算法:Hash算法和解决Hash碰撞冲突的算法
Hsh算法是一种数字摘要算法,将不定长度的二进制数据集给映射到一个较短的二进制长度数据集。实现Hash算法的函数称为Hash函数。
private struct Entry{
public int hashCode;
public int next;
public TKey key;
public TValue value;
}
private int[] buckets;
private Entry[] entries;
dic.Add("a",111);
- hashCode(a) = 10;
- 10%7=3
- buckets[3] = 0;
- 把值存在Entry类型数组里,位置为0
- 长度不够会扩容,长度为素数,因为对素数取余得到的余数冲突的概率最小,可以均匀分布在数组中
因为得到的余数可能会有相同的值,所以会冲突
解决方法
在Entry结构体中,添加了next,如果在同数组下标,添加了多个数据,那会在next记录原来这个位置的值,记录原理的下标,在通过键找到对应的下标后,判断此下标的对应的结构体里的Key是不是与自己的键值相等,相等则取结构体Entry内的value值,否则,通过该结构体的next值查询原来该位置的值,重复判断到找到相同的Key