C# Queue<T>源码浅析

所在框架版本:.Net Framework 4.0.30319

1.部分变量

private T[] _array;   //元素数组
private int _head;    //队头
private int _tail;    //队尾
private int _size;  //元素个数
private int _version;  //版本号
[NonSerialized]
private object _syncRoot;
private const int _MinimumGrow = 4;
private const int _ShrinkThreshold = 32;
private const int _GrowFactor = 200;
private const int _DefaultCapacity = 4;  //默认容量
private static T[] _emptyArray = new T[0];  //默认空数组

2.构造函数

public Queue() => this._array = Queue<T>._emptyArray;
public Queue(int capacity)   
    {
      if (capacity < 0)
        ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.capacity, ExceptionResource.ArgumentOutOfRange_NeedNonNegNumRequired);
      this._array = new T[capacity];   //初始化数组
      this._head = 0;  //队头初始化
      this._tail = 0;  //队尾初始化
      this._size = 0;   //元素个数初始化
    }
public Queue(IEnumerable<T> collection)
    {
      if (collection == null)
        ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection);
      this._array = new T[4];   //数组初始化长度为4
      this._size = 0;   
      this._version = 0;  
      foreach (T obj in collection)
        this.Enqueue(obj);   //元素入队
    }

3.清空

public void Clear()
    {
      if (this._head < this._tail)    //如果队头小于队尾
      {
        Array.Clear((Array) this._array, this._head, this._size);   //直接从队头开始清除
      }
      else
      {
        Array.Clear((Array) this._array, this._head, this._array.Length - this._head);   //先把队头到数组最后的部分清除
        Array.Clear((Array) this._array, 0, this._tail);   //最后清除从0到队尾的部分
      }
      this._head = 0;
      this._tail = 0;
      this._size = 0;
      ++this._version;   //版本号更新
    }

4.查找

public bool Contains(T item)
    {
      int index = this._head;
      int size = this._size;
      EqualityComparer<T> equalityComparer = EqualityComparer<T>.Default;
      while (size-- > 0)
      {
        if ((object) item == null)
        {
          if ((object) this._array[index] == null)
            return true;
        }
        else if ((object) this._array[index] != null && equalityComparer.Equals(this._array[index], item))   //如果不为空且值相等
          return true;
        index = (index + 1) % this._array.Length;   
      }
      return false;
    }

5.复制

public void CopyTo(T[] array, int arrayIndex)
    {
      if (array == null)
        ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
      if (arrayIndex < 0 || arrayIndex > array.Length)   
        ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.arrayIndex, ExceptionResource.ArgumentOutOfRange_Index);
      int length1 = array.Length;
      if (length1 - arrayIndex < this._size)
        ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidOffLen);
      int num = length1 - arrayIndex < this._size ? length1 - arrayIndex : this._size;   
      if (num == 0)
        return;
      int length2 = this._array.Length - this._head < num ? this._array.Length - this._head : num;
      Array.Copy((Array) this._array, this._head, (Array) array, arrayIndex, length2);   //拷贝队头到数组末尾部分
      int length3 = num - length2;
      if (length3 <= 0)
        return;
      Array.Copy((Array) this._array, 0, (Array) array, arrayIndex + this._array.Length - this._head, length3);  //拷贝剩余部分
    }

6.入队

public void Enqueue(T item)
    {  
      if (this._size == this._array.Length)   //满了
      {
        int capacity = (int) ((long) this._array.Length * 200L / 100L);   //扩容
        if (capacity < this._array.Length + 4)     //如果扩容后的容量小于当前当前容量加4
          capacity = this._array.Length + 4;
        this.SetCapacity(capacity);
      }
      this._array[this._tail] = item;    //插入队尾
      this._tail = (this._tail + 1) % this._array.Length;   //队尾更新
      ++this._size;  //元素个数更新
      ++this._version;  //版本号更新
    }

7.出队

public T Dequeue()
    {
      if (this._size == 0)
        ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EmptyQueue);
      T obj = this._array[this._head];    //获得队头元素
      this._array[this._head] = default (T);  //多头元素边为默认值
      this._head = (this._head + 1) % this._array.Length;  //队头位置后移
      --this._size;   //元素个数键一
      ++this._version;  //版本号更新
      return obj;
    }

8.Peek

public T Peek()
    {
      if (this._size == 0)
        ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EmptyQueue);
      return this._array[this._head];   //返回队头元素
    }

9.扩容

private void SetCapacity(int capacity)
    {
      T[] objArray = new T[capacity];   //新建数组
      if (this._size > 0)    //如果已有元素数大于0
      {
        if (this._head < this._tail)   //如果队头小于队尾
        {
          Array.Copy((Array) this._array, this._head, (Array) objArray, 0, this._size);   //直接拷贝
        }
        else  //否则分开拷贝
        {
          Array.Copy((Array) this._array, this._head, (Array) objArray, 0, this._array.Length - this._head);  
          Array.Copy((Array) this._array, 0, (Array) objArray, this._array.Length - this._head, this._tail);
        }
      }
      this._array = objArray;   //重新赋值数组
      this._head = 0;   //队头置0
      this._tail = this._size == capacity ? 0 : this._size;  //队尾重置
      ++this._version;   //版本号更新
    }

9.转换成数组

public T[] ToArray()
    {
      T[] objArray = new T[this._size];  //新建数组
      if (this._size == 0)   //如果元素个数为0,直接返回
        return objArray;
      if (this._head < this._tail)    //如果队头小于队尾
      {
        Array.Copy((Array) this._array, this._head, (Array) objArray, 0, this._size);   //直接拷贝
      }
      else   //否则分开拷贝
      {
        Array.Copy((Array) this._array, this._head, (Array) objArray, 0, this._array.Length - this._head);
        Array.Copy((Array) this._array, 0, (Array) objArray, this._array.Length - this._head, this._tail);
      }
      return objArray;  
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值