280 lines
5.2 KiB
Markdown
280 lines
5.2 KiB
Markdown
|
|
# Queue
|
|||
|
|
概念:
|
|||
|
|
`Queue` 是 C# 提供的一个==非泛型队列集合==
|
|||
|
|
队列的特点是:==先进先出==
|
|||
|
|
|
|||
|
|
英文:
|
|||
|
|
`FIFO`:First In First Out
|
|||
|
|
|
|||
|
|
简单理解:
|
|||
|
|
像排队买东西
|
|||
|
|
先排队的人,先被处理
|
|||
|
|
|
|||
|
|
命名空间:
|
|||
|
|
```csharp
|
|||
|
|
using System.Collections;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
----
|
|||
|
|
# 通常用法
|
|||
|
|
1. 处理需要“按进入顺序依次处理”的数据
|
|||
|
|
2. 保存等待处理的任务
|
|||
|
|
3. 模拟排队、消息、请求等逻辑
|
|||
|
|
4. 学习队列这种数据结构
|
|||
|
|
|
|||
|
|
实际开发中:
|
|||
|
|
新代码更推荐使用 `Queue<T>`
|
|||
|
|
这里的 `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<T>`
|
|||
|
|
|
|||
|
|
----
|
|||
|
|
# 一句话记忆
|
|||
|
|
==Queue 是先进先出的集合,先进去的先出来。==
|
|||
|
|
|
|||
|
|
----
|
|||
|
|
# 面试/复习时怎么说
|
|||
|
|
可以这样答:
|
|||
|
|
|
|||
|
|
“Queue 是队列结构,特点是先进先出,也就是 FIFO。
|
|||
|
|
常用方法有 `Enqueue`、`Dequeue` 和 `Peek`,分别表示入队、出队、查看队头。
|
|||
|
|
非泛型 Queue 存的是 object,取值时可能需要强制类型转换,新项目中更推荐使用 `Queue<T>`。”
|
|||
|
|
|
|||
|
|
----
|
|||
|
|
引用:
|
|||
|
|
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
|
|||
|
|
#队列
|
|||
|
|
#集合
|
|||
|
|
#进阶
|