一、应用背景
项目中,需要将所有的计划信息加入服务器维护的静态字典对象中,key表示所有的计划信息,为自定义对象。value表示计划信息的状态,表示正在编辑或者完成。当用户每完成一条计划时,就会向服务器端发送计划信息。此时静态字典对象会判断新接收的信息是否已存在,如果没有,则加入字典中。
二、现象思考
使用Dictionary自带的函数ContainsKey比较时,会将所有的新对象都加入,即时自定义对象中各项的值都与字典中某一项相同,这是怎么回事呢?这时回到ContainsKey的源码思考了~
字典是如何对键值进行比较的呢?
三、理解hash算法
在字典的结构中,键和值是通过哈希表的方式存储的,但如果键/值很多的时候,使用哈希算法有可能会出现键/值的哈希码一致的情况。总结一下,hash中存在的情况:
1、同一个hash对象,hash码必定相同
2、不同的hash对象,hash码有可能相同
对于第二种情况,我们称为hash碰撞冲突,那在.Net中是如何解决碰撞冲突的呢?
拉链法:即出现hash冲突时,将冲突的元素都存在同一个链表上。上图:
字典中是如何使用哈希结构的呢?首先获得Key对象的一个hashCode,这个hashCode指向一个内存地址,用于存放键值。
现在理解就很容易了!判断字典中是否有已存在的Key,不仅要保证hashCode相等,由于hash冲突,还有检查是否Key的内容“相等”(这里指我们自定义的相等,不一定是绝对相等)。
四、重写GethashCode和Equals
回过来再看二的现象,对于一个各方面都相等的自定义Key,为什么每次字典都返回不存在呢?
想想判断方法,