DotNet 源码学习——QUEUE

1、Queue声明创建对象。(Queue为泛型对象。)

public class Queue<T> :IEnumerable<T>,System.Collections.ICollection,IReadOnlyCollection<T>

 

本质为Array对象存储数据。

 

Queue<string> qy = new Queue<string>();
private T[] _array
public Queue()
{
    _array = Array.Empty<T>();
}
Queue<int> qy1 = new Queue<int>(12);
public Queue(int capacity)
{
    if (capacity < 0)
        throw new ArgumentOutOfRangeException(nameof(capacity), capacity, SR.ArgumentOutOfRange_NeedNonNegNum);
    _array = new T[capacity];
}
Queue<int> qy2 = new Queue<int>(new List<int>());

public Queue(IEnumerable<T> collection)
{
    if (collection == null)
        throw new ArgumentNullException(nameof(collection));

    _array = EnumerableHelpers.ToArray(collection, out _size);
    if (_size != _array.Length) _tail = _size;
}

 

2、队列的空间是实际存储值的两倍,如果小于两倍则每次增场4的长度。

 

 

 

1 if (_size == _array.Length)
2 {
3      int newcapacity = (int)((long)_array.Length * (long)GrowFactor / 100);
4      if (newcapacity < _array.Length + MinimumGrow)
5      {
6          newcapacity = _array.Length + MinimumGrow;
7      }
8      SetCapacity(newcapacity);
9 }

 

3、Queue为先进先出。

 

进队列在数组末尾赋值

 

        public void Enqueue(T item)
        {
            if (_size == _array.Length)
            {
                int newcapacity = (int)((long)_array.Length * (long)GrowFactor / 100);
                if (newcapacity < _array.Length + MinimumGrow)
                {
                    newcapacity = _array.Length + MinimumGrow;
                }
                SetCapacity(newcapacity);
            }

            _array[_tail] = item;
            MoveNext(ref _tail);
            _size++;
            _version++;
        }

 

出队列则从头部取值

 

 

        public T Dequeue()
        {
            int head = _head;
            T[] array = _array;

            if (_size == 0)
            {
                ThrowForEmptyQueue();
            }

            T removed = array[head];
            if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
            {
                array[head] = default!;
            }
            MoveNext(ref _head);
            _size--;
            _version++;
            return removed;
        }    

 

4、TryDequeue  Dequeue()区别在于 TryDequeue 判断size为0时,返回false 并out 泛型的默认值

 

 

        public bool TryDequeue([MaybeNullWhen(false)] out T result)
        {
            int head = _head;
            T[] array = _array;

            if (_size == 0)
            {
                result = default!;
                return false;
            }

            result = array[head];
            if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
            {
                array[head] = default!;
            }
            MoveNext(ref _head);
            _size--;
            _version++;
            return true;
        }    

 

注:MaybeNullWhenAttribute(Boolean) 返回值条件。 如果方法返回此值,则关联的参数可能为 null

 

 

5、Peek 仅仅时查看一下下一个要返回的值,不从数组移除

 

            if (_size == 0)
            {
                result = default!;
                return false;
            }

            result = _array[_head];
            return true;            

 

随是拙见,但为原创,转载注明出处,敬谢

Queue 常用的方法大约就这些。先写道这里,碎觉。

以下为公众号,一起学起来~

 

posted @ 2020-02-10 23:38  温暖如太阳  阅读(266)  评论(0编辑  收藏  举报