C#中QueueT类的使用以及部分方法的源码分析
标签:
Queue<T>类 表示对象的先进先出集合。 队列在按接收顺序存储消息方面非常有用,以便于进行顺序处理。 存储在 Queue,<T> 中的对象在一端插入,从另一端移除。 Queue<T> 的容量是 Queue<T> 可以包含的元素数。 当向 Queue<T> 中添加元素时,将通过重新分配内部数组来根据需要自动增大容量。 可通过调用 TrimExcess 来减少容量。 Queue<T> 接受 null 作为引用类型的有效值并且允许有重复的元素。 命名控件:System.Collections.Generic 程序集:System(在System.dll中) 语法:public class Queue<T>:IEnumerable<T>, ICollection, IEnumerable List<T>实现了IList<T>、 ICollection<T>、IEnumerable<T>、IList、ICollection、IEnumerable接口 因此可以看出与List<T>相比: Queue<T>没有继承ICollection<T>接口,因为这个接口定义的Add()和Remove()方法不能用于队列; Queue<T>没有继承IList<T>接口,所以不能使用索引器访问队列。 所以队列只允许在队列的尾部添加元素,从队列的头部获取元素。 常用的Queue<T>类的成员: Count : 返回队列中元素的个数。 Enqueue : 在队列一端添加一个元素。 Dequeue() : 从队列的头部读取和删除一个元素。如果调用Dequeue()时,队列中没有元素就会抛出异常InvalidOperationException异常。 Peek(): 在队列的头部取出一个元素,但不删除它。 TrimExcess():重置队列的容量。 /******************************************************************************************************************************/ 常用Queue<T>类的成员函数的源码如下: 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--; this._version++; return local; } 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++; this._version++; } public T Peek() { if (this._size == 0) { ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EmptyQueue); } return this._array[this._head]; } public void TrimExcess() { int num = (int) (this._array.Length * 0.9); if (this._size < num) { this.SetCapacity(this._size); } } 上诉方法使用到的SetCapacity函数的源码如下: private void SetCapacity(int capacity) { T[] destinationArray = new T[capacity]; if (this._size > 0) { if (this._head < this._tail) { Array.Copy(this._array, this._head, destinationArray, 0, this._size); } else { Array.Copy(this._array, this._head, destinationArray, 0, this._array.Length - this._head); Array.Copy(this._array, 0, destinationArray, this._array.Length - this._head, this._tail); } } this._array = destinationArray; this._head = 0; this._tail = (this._size == capacity) ? 0 : this._size; this._version++; } /*****************************************************************************************************************************************/ 示例: 下面的代码示例演示了 Queue<T> 泛型类的几个方法。 此代码示例创建一个具有默认容量的字符串队列,并使用 Enqueue 方法对五个字符串进行排队。 枚举队列元素,,这不会更改队列的状态。 使用 Dequeue 方法使第一个字符串出列。 使用 Peek 方法查找队列中的下一项,然后使用 Dequeue 方法使该项出列。 使用 ToArray 方法创建一个数组并将队列元素复制到该数组,然后将该数组传递给接受 IEnumerable 的 Queue 构造函数以创建队列副本。 将显示副本的元素。 创建一个大小是队列大小两倍的数组,并使用 CopyTo 方法从数组中间开始复制数组元素。 再次使用 Queue1T> 构造函数创建第二个队列副本,此队列在开始处包含三个 null 元素。 使用 Contains 方法显示字符串“four”在第一个队列副本中,然后使用 Clear 方法清除此副本并由 Count 属性显示该队列为空。 using System; using System.Collections.Generic; class Example { public static void Main() { Queue1string> numbers = new Queue1string>(); numbers.Enqueue("one"); numbers.Enqueue("two"); numbers.Enqueue("three"); numbers.Enqueue("four"); numbers.Enqueue("five"); // A queue can be enumerated without disturbing its contents. foreach( string number in numbers ) { Console.WriteLine(number); } Console.WriteLine("\nDequeuing ‘{0}‘", numbers.Dequeue()); Console.WriteLine("Peek at next item to dequeue: {0}", numbers.Peek()); Console.WriteLine("Dequeuing ‘{0}‘", numbers.Dequeue()); // Create a copy of the queue, using the ToArray method and the // constructor that accepts an IEnumerable. Queue1string> queueCopy = new Queue1string>(numbers.ToArray()); Console.WriteLine("\nContents of the first copy:"); foreach( string number in queueCopy ) { Console.WriteLine(number); } // Create an array twice the size of the queue and copy the // elements of the queue, starting at the middle of the // array. string[] array2 = new string[numbers.Count * 2]; numbers.CopyTo(array2, numbers.Count); // Create a second queue, using the constructor that accepts an // IEnumerable(Of T). Queue1string> queueCopy2 = new Queue1string>(array2); Console.WriteLine("\nContents of the second copy, with duplicates and nulls:"); foreach( string number in queueCopy2 ) { Console.WriteLine(number); } Console.WriteLine("\nqueueCopy.Contains(\"four\") = {0}", queueCopy.Contains("four")); Console.WriteLine("\nqueueCopy.Clear()"); queueCopy.Clear(); Console.WriteLine("\nqueueCopy.Count = {0}", queueCopy.Count); } } /* This code example produces the following output: one two three four five Dequeuing ‘one‘ Peek at next item to dequeue: two Dequeuing ‘two‘ Contents of the copy: three four five Contents of the second copy, with duplicates and nulls: three four five queueCopy.Contains("four") = True queueCopy.Clear() queueCopy.Count = 0 */
版权声明:本文为博主原创文章,未经博主允许不得转载。
温馨提示: 本文由Jm博客推荐,转载请保留链接: https://www.jmwww.net/file/69116.html