# Queue 概念: `Queue` 是 C# 提供的一个==非泛型队列集合== 队列的特点是:==先进先出== 英文: `FIFO`:First In First Out 简单理解: 像排队买东西 先排队的人,先被处理 命名空间: ```csharp using System.Collections; ``` ---- # 通常用法 1. 处理需要“按进入顺序依次处理”的数据 2. 保存等待处理的任务 3. 模拟排队、消息、请求等逻辑 4. 学习队列这种数据结构 实际开发中: 新代码更推荐使用 `Queue` 这里的 `Queue` 是非泛型版本 ---- # 语法 创建: ```csharp Queue queue = new Queue(); ``` 入队: ```csharp queue.Enqueue(数据); ``` 出队: ```csharp object value = queue.Dequeue(); ``` 查看队头: ```csharp object value = queue.Peek(); ``` 数量: ```csharp queue.Count ``` ---- # 基础案例 ```csharp using System; using System.Collections; Queue queue = new Queue(); queue.Enqueue("第一个任务"); queue.Enqueue("第二个任务"); queue.Enqueue("第三个任务"); Console.WriteLine(queue.Dequeue()); Console.WriteLine(queue.Dequeue()); Console.WriteLine(queue.Dequeue()); ``` 输出: ```text 第一个任务 第二个任务 第三个任务 ``` 理解: 1. `"第一个任务"` 最先进队列 2. `Dequeue()` 会先取出最早进入队列的元素 3. 这就是先进先出 ---- # Enqueue、Dequeue、Peek `Enqueue`: 把元素添加到队尾 ```csharp queue.Enqueue("A"); ``` `Dequeue`: 取出并删除队头元素 ```csharp object item = queue.Dequeue(); ``` `Peek`: 查看队头元素,但不删除 ```csharp object item = queue.Peek(); ``` 案例: ```csharp Queue queue = new Queue(); queue.Enqueue("A"); queue.Enqueue("B"); Console.WriteLine(queue.Peek()); // A Console.WriteLine(queue.Count); // 2 Console.WriteLine(queue.Dequeue()); // A Console.WriteLine(queue.Count); // 1 ``` ---- # 遍历 ```csharp Queue queue = new Queue(); queue.Enqueue("A"); queue.Enqueue("B"); queue.Enqueue("C"); foreach (object item in queue) { Console.WriteLine(item); } ``` 输出顺序一般是: ```text A B C ``` 理解: 遍历 `Queue` 时,通常按入队顺序从队头到队尾遍历 ---- # 常用成员 ```csharp Queue queue = new Queue(); queue.Enqueue("A"); queue.Enqueue("B"); Console.WriteLine(queue.Count); Console.WriteLine(queue.Contains("A")); object first = queue.Peek(); object value = queue.Dequeue(); queue.Clear(); ``` 常用方法: 1. `Enqueue(object obj)`:入队 2. `Dequeue()`:出队并删除 3. `Peek()`:查看队头但不删除 4. `Contains(object obj)`:判断是否包含 5. `Clear()`:清空 6. `ToArray()`:转成数组 ---- # 空队列不能 Dequeue 或 Peek 错误写法: ```csharp Queue queue = new Queue(); queue.Dequeue(); ``` 原因: 队列里没有元素,不能取队头 更稳的写法: ```csharp if (queue.Count > 0) { object value = queue.Dequeue(); } ``` `Peek()` 也一样,使用前最好先判断 `Count`。 ---- # 取值时要类型转换 ```csharp Queue queue = new Queue(); queue.Enqueue(100); int num = (int)queue.Dequeue(); ``` 原因: 非泛型 `Queue` 中的元素按 `object` 存储 取出来也是 `object` 值类型入队和出队时,也会涉及装箱拆箱: ```csharp queue.Enqueue(100); // 装箱 int num = (int)queue.Dequeue(); // 拆箱 ``` ---- # 适合场景:任务队列 ```csharp Queue taskQueue = new Queue(); taskQueue.Enqueue("加载配置"); taskQueue.Enqueue("读取存档"); taskQueue.Enqueue("进入场景"); while (taskQueue.Count > 0) { string task = (string)taskQueue.Dequeue(); Console.WriteLine("处理:" + task); } ``` 理解: 任务按照加入顺序依次处理 这种情况适合用队列 ---- # Queue 和 Stack 的区别 | 对比点 | Queue | Stack | |---|---|---| | 规则 | 先进先出 | 后进先出 | | 英文 | FIFO | LIFO | | 添加 | `Enqueue` | `Push` | | 取出 | `Dequeue` | `Pop` | | 查看 | `Peek` 查看队头 | `Peek` 查看栈顶 | | 适合场景 | 排队处理任务 | 撤销、回退 | 一句话: 排队用 `Queue` 回退用 `Stack` ---- # 注意 1. `Queue` 在 `System.Collections` 命名空间中 2. `Queue` 是非泛型集合,元素按 `object` 存储 3. 队列的规则是先进先出 4. `Enqueue` 是入队 5. `Dequeue` 是出队并删除队头 6. `Peek` 是查看队头但不删除 7. 空队列调用 `Dequeue()` 或 `Peek()` 会出错 8. 新项目通常优先使用 `Queue` ---- # 一句话记忆 ==Queue 是先进先出的集合,先进去的先出来。== ---- # 面试/复习时怎么说 可以这样答: “Queue 是队列结构,特点是先进先出,也就是 FIFO。 常用方法有 `Enqueue`、`Dequeue` 和 `Peek`,分别表示入队、出队、查看队头。 非泛型 Queue 存的是 object,取值时可能需要强制类型转换,新项目中更推荐使用 `Queue`。” ---- 引用: 1. Microsoft Learn: [Queue Class](https://learn.microsoft.com/en-us/dotnet/api/system.collections.queue?view=net-9.0) 2. Microsoft Learn: [Queue.Enqueue Method](https://learn.microsoft.com/en-us/dotnet/api/system.collections.queue.enqueue?view=net-9.0) 3. Microsoft Learn: [System.Collections Namespace](https://learn.microsoft.com/en-us/dotnet/api/system.collections?view=net-9.0) #Queue #队列 #集合 #进阶