inforasc

美好的每一天

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
这几天来,结合着Reflector工具,在学习泛型集合方面的基础知识,也连续写了几篇笔记文章,今天继续Queue的学习,主要是利用Reflector查看其内部的实现,以加深对基础知识的理解:
  1、Queue<T>队列,表示对象的先进先出集合(MSDN)
  2、主要私有成员变量:
    private T[] _array;//队列的存储与操作基于此数组实现
    private int _head;//头指针
    private int _tail;//尾指针
    private int _size;//大小,用于返回Count
    当调用构造函数时,都会初始化_array;
    特别的:
    public Queue(IEnumerable<T> collection)
    {
        if (collection == null)
        {
            ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection);
        }
        this._array = new T[4];//设置默认大小
        this._size = 0;
        this._version = 0;
        using (IEnumerator<T> enumerator = collection.GetEnumerator())//遍历Collection元素并压入队列
        {
            while (enumerator.MoveNext())
            {
                this.Enqueue(enumerator.Current);
            }
        }
    }
    从代码可以看出:默认_array的Length是4(在调用Enqueue()时,会根据需要再分配),同时实现了元素的复制。
  3、主要方法及属性:
    Enqueue(T item):将元素添加到队列的结尾处;
    public void Enqueue(T item)
    {
       if (this._size == this._array.Length) //判断是否需要增加容量
        {
            int capacity = (int) ((this._array.Length * 200L) / 100L);
            if (capacity < (this._array.Length + 4))
            {
                capacity = this._array.Length + 4;
            }
            this.SetCapacity(capacity);//增加容量
        }
        this._array[this._tail] = item;//将元素压入队列
        this._tail = (this._tail + 1) % this._array.Length;//修改尾指针
        this._size++;//Count值增加
        this._version++;
    }
    Dequeue():移除 并 返回 队列 头位置的元素
    public T Dequeue()
    {
        if (this._size == 0)//如果队列为空,则抛出异常
        {
           ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EmptyQueue);
        }
        T local = this._array[this._head];//获取 头位置元素
        this._array[this._head] = default(T);
        this._head = (this._head + 1) % this._array.Length;//修改头指针,以指向下一个元素
        this._size--;//Count值减少
        this._version++;
        return local;
    }
    Peek():返回队列开始处元素,但是并不改变队列
    public T Peek()
    {
        if (this._size == 0)//如果队列为空,则抛出异常
        {
           ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EmptyQueue);
        }
        return this._array[this._head];//返回头指针处元素
    }
    Count:获取队列中包含的元素数
    public int Count
    {
        get
        {
            return this._size; //Enqueue()Dequeue()以及Clear()都会影响_size的值
        }
    }
  4、常用操作:
   1)、入队:
     Queue<string> myQueue = new Queue<string>();
            myQueue.Enqueue("1");
            myQueue.Enqueue("2");
            myQueue.Enqueue("3");
            myQueue.Enqueue("4");
            myQueue.Enqueue("5");
            myQueue.Enqueue("6");
   2)、出队:
     Console.WriteLine("调用Dequeue()之前,Count:{0}", myQueue.Count);
            myQueue.Dequeue();
            Console.WriteLine("调用Dequeue()之后,Count:{0}",myQueue.Count);
   3)、遍历元素:
     foreach (string num in myQueue)
            {
                Console.WriteLine("Foreach Queue El : {0}", num);
            }
    //另一种方式:
     using (IEnumerator<string> num = myQueue.GetEnumerator())
            {
                while (num .MoveNext())
                {
                    Console.WriteLine("Enumerator Queue EL: {0}", num .Current);
                }
            }   
  4)、复制元素:
     Queue<string> queueCopy = new Queue<string>(myQueue.ToArray());
            foreach (string copy in queueCopy)
            {
                Console.WriteLine("Copy Array:{0}", copy);
            }
   5)、移除队列中所有元素:
      Console.WriteLine("调用Clear()之前,Count:{0}", myQueue.Count);
             myQueue.Clear();
             Console.WriteLine("调用Clear()之后,Count:{0}",myQueue.Count);
posted on 2009-10-06 10:34  inforasc  阅读(1343)  评论(0编辑  收藏  举报