C#创建安全的字典(Dictionary)存储结构

2019-12-30 15:02:13刘景俊

在上面介绍过栈(Stack)的存储结构,接下来介绍另一种存储结构字典(Dictionary)。 字典(Dictionary)里面的每一个元素都是一个键值对(由二个元素组成:键和值) 键必须是唯一的,而值不需要唯一的,键和值都可以是任何类型。字典(Dictionary)是常用于查找和排序的列表。

  接下来看一下Dictionary的部分方法和类的底层实现代码:

  1.Add:将指定的键和值添加到字典中。


  public void Add(TKey key, TValue value) {
      Insert(key, value, true); 
    }
 private void Insert(TKey key, TValue value, bool add) {
       if( key == null ) { 
        ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
      } 
      if (buckets == null) Initialize(0);
      int hashCode = comparer.GetHashCode(key) & 0x7FFFFFFF;
      int targetBucket = hashCode % buckets.Length; 
#if FEATURE_RANDOMIZED_STRING_HASHING 
      int collisionCount = 0; 
#endif
      for (int i = buckets[targetBucket]; i >= 0; i = entries[i].next) {
        if (entries[i].hashCode == hashCode && comparer.Equals(entries[i].key, key)) {
          if (add) {
            ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_AddingDuplicate); 
          }
          entries[i].value = value; 
          version++; 
          return;
        } 
#if FEATURE_RANDOMIZED_STRING_HASHING
        collisionCount++;
#endif 
      }
      int index; 
      if (freeCount > 0) { 
        index = freeList;
        freeList = entries[index].next; 
        freeCount--;
      }
      else {
        if (count == entries.Length) 
        {
          Resize(); 
          targetBucket = hashCode % buckets.Length; 
        }
        index = count; 
        count++;
      }
      entries[index].hashCode = hashCode; 
      entries[index].next = buckets[targetBucket];
      entries[index].key = key; 
      entries[index].value = value; 
      buckets[targetBucket] = index;
      version++; 
#if FEATURE_RANDOMIZED_STRING_HASHING
      if(collisionCount > HashHelpers.HashCollisionThreshold && HashHelpers.IsWellKnownEqualityComparer(comparer))
      { 
        comparer = (IEqualityComparer<TKey>) HashHelpers.GetRandomizedEqualityComparer(comparer);
        Resize(entries.Length, true); 
      } 
#endif
    }

  2.Clear():从 Dictionary<TKey, TValue> 中移除所有的键和值。


 public void Clear() {
      if (count > 0) {
        for (int i = 0; i < buckets.Length; i++) buckets[i] = -1;
        Array.Clear(entries, 0, count); 
        freeList = -1;
        count = 0; 
        freeCount = 0; 
        version++;
      } 
    }

   3.Remove():从 Dictionary<TKey, TValue> 中移除所指定的键的值。


 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; 
        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);
            freeList = i; 
            freeCount++;
            version++; 
            return true; 
          }
        } 
      }
      return false;
    }