通过源代码分析C#Dictionary的关键实现

1.Dictionary的Add实现。

   在Dictionary内部有几个关键字段,他们是理解Dictionary的关键。这些关键字段如下:

   private int[] buckets;

   private Dictionary<TKey, TValue>.Entry[] entries;

   private IEqualityComparer<TKey> compare

这几个字段的用途稍后讲解。

接下来看一下Add方法的实现,如下:

   public void Add(TKey key, TValue value)
    {
      this.Insert(key, value, true);
    }
可知,Add方法调用了一个Insert方法,转到Insert的内部实现如下:

private void Insert(TKey key, TValue value, bool add)
    {
      if ((object) key == null)
        ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
      if (this.buckets == null)
        this.Initialize(0);
      int num = this.comparer.GetHashCode(key) & int.MaxValue;
      int index1 = num % this.buckets.Length;
      for (int index2 = this.buckets[index1]; index2 >= 0; index2 = this.entries[index2].next)
      {
        if (this.entries[index2].hashCode == num && this.comparer.Equals(this.entries[index2].key, key))
        {
          if (add)
            ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_AddingDuplicate);
          this.entries[index2].value = value;
          ++this.version;
          return;
        }
      }
      int index3;
      if (this.freeCount > 0)
      {
        index3 = this.freeList;
        this.freeList = this.entries[index3].next;
        --this.freeCount;
      }
      else
      {
        if (this.count == this.entries.Length)
        {
          this.Resize();
          index1 = num % this.buckets.Length;
        }
        index3 = this.count;
        ++this.count;
      }
      this.entries[index3].hashCode = num;
      this.entries[index3].next = this.buckets[index1];
      this.entries[index3].key = key;
      this.entries[index3].value = value;
      this.buckets[index1] = index3;
      ++this.version;
    }

这段代码有点长,但只要静下心来很容易看懂。有些不重要的代码暂且不论,分析如下:

1.首先判断,key是否为null,如果为null就抛出一个ArgumentNullException异常。

2.使用IEqualityComparer来获取关键字key的哈希值,然后于int的最大值做与运算,将结果赋值给num。代码如下:

 int num = this.comparer.GetHashCode(key) & int.MaxValue;

3.将num于bucketes.Length做模运算,结果是一个小于length的值,这样这个值就可以索引bucketes了。

int index1 = num % this.buckets.Length;

4.判断bucketes中是否有要插入的关键字了,这是通过一个for循环来实现的。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值