C# Queue 类用法说明

325 阅读3分钟

Queue 类是 C# 中用于实现先进先出(FIFO)集合的数据结构。它位于 System.Collections 命名空间中,允许你在一端(队尾)添加元素,在另一端(队头)移除元素。

Queue 类的主要特点

  1. 先进先出(FIFO) :最先添加的元素会最先被移除。
  2. 动态大小Queue 的大小会根据需要自动增长。
  3. 泛型支持Queue<T> 是泛型版本,支持类型安全。
  4. 常用操作:提供入队(Enqueue)、出队(Dequeue)、查看队头元素(Peek)等操作。

Queue 类的常用属性和方法

属性

  • Count:获取队列中元素的数量。

方法

  • Enqueue(T item) :将元素添加到队列的末尾。
  • Dequeue() :移除并返回队列开头的元素。
  • Peek() :返回队列开头的元素但不移除它。
  • Clear() :移除队列中的所有元素。
  • Contains(T item) :检查队列中是否包含指定元素。
  • ToArray() :将队列中的元素复制到新数组中。
  • TrimExcess() :如果元素数量小于当前容量的 90%,则将容量减少到实际元素数量。

Queue 的基本用法

1. 创建队列

using System;
using System.Collections;

class Program
{
    static void Main()
    {
        // 创建一个非泛型队列
        Queue queue = new Queue();

        // 创建一个泛型队列(推荐使用)
        Queue<int> genericQueue = new Queue<int>();
    }
}

2. 添加元素(Enqueue)

Queue<string> queue = new Queue<string>();
queue.Enqueue("Apple");
queue.Enqueue("Banana");
queue.Enqueue("Cherry");

Console.WriteLine("Queue elements:");
foreach (var item in queue)
{
    Console.WriteLine(item);
}

3. 移除元素(Dequeue)

string firstItem = queue.Dequeue();
Console.WriteLine($"Dequeued item: {firstItem}");

Console.WriteLine("Queue after Dequeue:");
foreach (var item in queue)
{
    Console.WriteLine(item);
}

4. 查看队头元素(Peek)

string peekItem = queue.Peek();
Console.WriteLine($"Peeked item: {peekItem}");

5. 检查队列是否包含某个元素

bool containsBanana = queue.Contains("Banana");
Console.WriteLine($"Queue contains 'Banana': {containsBanana}");

6. 清空队列

queue.Clear();
Console.WriteLine($"Queue count after Clear: {queue.Count}");

示例代码

以下是一个完整的示例,演示了 Queue 的基本操作:

using System;
using System.Collections;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        // 创建一个泛型队列
        Queue<string> queue = new Queue<string>();

        // 添加元素
        queue.Enqueue("Apple");
        queue.Enqueue("Banana");
        queue.Enqueue("Cherry");

        // 查看队列中的元素
        Console.WriteLine("Queue elements:");
        foreach (var item in queue)
        {
            Console.WriteLine(item);
        }

        // 查看队头元素
        string peekItem = queue.Peek();
        Console.WriteLine($"Peeked item: {peekItem}");

        // 移除队头元素
        string firstItem = queue.Dequeue();
        Console.WriteLine($"Dequeued item: {firstItem}");

        // 检查队列是否包含某个元素
        bool containsBanana = queue.Contains("Banana");
        Console.WriteLine($"Queue contains 'Banana': {containsBanana}");

        // 清空队列
        queue.Clear();
        Console.WriteLine($"Queue count after Clear: {queue.Count}");
    }
}

输出结果

Queue elements:
Apple
Banana
Cherry
Peeked item: Apple
Dequeued item: Apple
Queue contains 'Banana': True
Queue count after Clear: 0

Queue 的泛型版本(Queue)

Queue<T> 是 Queue 的泛型版本,提供了类型安全的操作。它的用法与非泛型版本类似,但不需要进行类型转换。

    Queue<int> intQueue = new Queue<int>();
intQueue.Enqueue(10);
intQueue.Enqueue(20);
intQueue.Enqueue(30);

int firstNumber = intQueue.Dequeue();
Console.WriteLine($"Dequeued number: {firstNumber}");

注意事项

  1. 空队列操作:如果对空队列调用 Dequeue() 或 Peek(),会抛出 InvalidOperationException。因此,在调用这些方法之前,最好检查 Count 属性。
  2. 性能Queue 的入队和出队操作的时间复杂度为 O(1),适合需要频繁添加和移除元素的场景。

总结

Queue 是一个简单而强大的数据结构,适用于需要先进先出逻辑的场景。通过 EnqueueDequeue 和 Peek 等方法,可以轻松管理队列中的元素。泛型版本 Queue<T> 提供了更好的类型安全性和性能。

     public class ErrorLogger
    {
        private static ILog logger = log4net.LogManager.GetLogger("Demo");
        public static void StartLogging()
        {
            while (true)
            {
                var ex = ExceptionQueue.Dequeue();
                if (ex == null)
                {
                    Thread.Sleep(5000);
                    continue;
                }

                logger.Error(ex.Message, ex);
            }
        }
    }
    public static class ExceptionQueue
    {
        private static Queue<Exception> _exceptionQueue = new Queue<Exception>();            
        public static Queue<Exception> Queue { get { return _exceptionQueue; } }

        public static void Enqueue(Exception ex)
        {
            lock (_exceptionQueue)
            {
                _exceptionQueue.Enqueue(ex);
            }
        }
        public static Exception Dequeue()
        {
            Exception e;
            lock (_exceptionQueue)
            {
                if (_exceptionQueue.Count == 0)
                {
                    return null;
                }
                e = _exceptionQueue.Dequeue();
            }
            return e;
        }
    }