C# Queue(队列)

Queue是一种特殊的集合类型,它以FIFO方式(先进先出)存储元素,与Stack <T>集合完全相反。它按添加顺序包含元素。C#包括泛型Queue<T>和非泛型Queue集合。建议使用泛型Queue<T>集合。

Queue <T>特性

  • Queue<T> 是FIFO(先进先出)集合。  

  • 它在System.Collection.Generic命名空间下。

  • Queue<T>可以包含指定类型的元素。它提供编译时类型检查,并且不执行装箱/拆箱,因为它是泛型的。

  • 可以使用Enqueue()方法添加元素。无法使用集合初始化(collection-initializer)语法。

  • 可以使用Dequeue() 和 Peek()方法检索元素。它不支持索引器。

下图说明了Queue集合:

C#队列

创建队列

您可以通过为 Queue<T> 其存储的元素类型指定类型参数来创建的对象。下面的示例使用 Enqueue ()方法在 Queue <T> 中创建和添加元素。Queue 集合允许 null (用于引用类型)和重复值。

Queue<int> callerIds = new Queue<int>();
callerIds.Enqueue(1);
callerIds.Enqueue(2);
callerIds.Enqueue(3);
callerIds.Enqueue(4);

foreach(var id in callerIds)
    Console.Write(id); //打印1234

Queue <T>属性和方法

属性用法
Count返回队列中元素的总数。
方法用法
Enqueue(T)将项目添加到队列中。
Dequeue从队列的开头返回一个项目,并将其从队列中删除。
Peek(T)从队列中返回第一个项目而不将其删除。
Contains(T)检查项目是否在队列中
Clear()从队列中删除所有项目。

从队列中检索元素

Dequeue()和Peek()方法用于检索在队列集合中的第一个元素。Dequeue()移除并返回一个队列中的第一个元素,因为在FIFO的顺序队列存储元素。在空队列上调用 Dequeue() 方法将引发InvalidOperation异常。因此,在调用队列之前,请始终检查队列的总数是否大于零。

Queue<string> strQ = new Queue<string>();
strQ.Enqueue("H");
strQ.Enqueue("e");
strQ.Enqueue("l");
strQ.Enqueue("l");
strQ.Enqueue("o");

Console.WriteLine("元素总数: {0}", strQ.Count); //输出 5

while (strQ.Count > 0){
    Console.WriteLine(strQ.Dequeue()); //输出 Hello
}


Console.WriteLine("元素总数: {0}", strQ.Count); //输出 0

Peek()方法始终从队列集合中返回第一项,而不会将其从队列中删除。Peek()在空队列上调用该方法将引发运行时异常 InvalidOperationException。

Queue<string> strQ = new Queue<string>();
strQ.Enqueue("H");
strQ.Enqueue("e");
strQ.Enqueue("l");
strQ.Enqueue("l");
strQ.Enqueue("o");

Console.WriteLine("元素总数: {0}", strQ.Count); //输出 5

if(strQ.Count > 0){
    Console.WriteLine(strQ.Peek()); //输出 H
    Console.WriteLine(strQ.Peek()); //输出 H
}

Console.WriteLine("元素总数: {0}", strQ.Count); //输出 0

Contains()

Contains()方法检查队列中是否存在项目。如果指定的项目存在,则返回true,否则返回false。

Contains() 签名:

 bool Contains(object obj);
Queue<int> callerIds = new Queue<int>();
callerIds.Enqueue(1);
callerIds.Enqueue(2);
callerIds.Enqueue(3);
callerIds.Enqueue(4);

callerIds.Contains(2); //true
callerIds.Contains(10); //false