public bool Remove(TKey key) {
if(key == null) {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
}
if (buckets != null) {
int hashCode = comparer.GetHashCode(key) & 0x7FFFFFFF;
int bucket = hashCode % buckets.Length;
int last = -1;
//其原理先取出键值,然后记录entries空闲的索引(freeList)和空闲个数(freeCount)
for (int i = buckets[bucket]; i >= 0; last = i, i = entries[i].next) {
if (entries[i].hashCode == hashCode && comparer.Equals(entries[i].key, key)) {
if (last < 0) {
buckets[bucket] = entries[i].next;
}
else {
entries[last].next = entries[i].next;
}
entries[i].hashCode = -1;
//建立空闲链表
entries[i].next = freeList;
entries[i].key = default(TKey);
entries[i].value = default(TValue);
//保存entryies中空元素的索引
//便于插入新键值时,放在当前索引的位置,减少entryies空间上的浪费
freeList = i;
//空元素的个数加1
freeCount++;
version++;
return true;
}
}
}
return false;
}
*******************************************************************
static void Foo()
{
......
//移除
new List<int> { 22, 29 }.ForEach(item => dicData.Remove(item));
}
如上图,当移除掉{36,36}后,会发现又诞生一个含有两个元素的“新链表”(上图灰色框)。这个作用就是为了插入新键值时,按照“新链表”记录的索引顺序插入到entries数组中。