前言

我们常用Queue<T>类来表示先进先出(FIFO)集合,集合中的对象按照放入顺序检索。例如:

var jobs = new Queue<Job>();jobs.Enqueue(new Job() { Id = 1 });
jobs.Enqueue(new Job() { Id = 2 });
jobs.Enqueue(new Job() { Id = 3 });while (jobs.TryDequeue(out var job))
{Console.WriteLine(job.Id);
}//输出
1
2
3

PriorityQueue

在.NET 6中,新增了PriorityQueue<TElement,TPriority>类,可以用来表示具有值和优先级的集合。集合中的对象按照优先级值从小到大的顺序检索。

例如,最后放入队列的任务最紧急,需要有限处理:

var jobs = new PriorityQueue<Job, int>(); jobs.Enqueue(new Job() { Id = 1 }, 100);
jobs.Enqueue(new Job() { Id = 2 }, 100);
jobs.Enqueue(new Job() { Id = 3 }, 1);while (jobs.TryDequeue(out var job,out var priority))
{Console.WriteLine(job.Id);
}//输出
3
1
2

自定义比较器

优先级TPriority不必是数字,可以是任何类型,只要它的实例之间能比较大小。甚至,我们可以使用自定义比较器,实现复杂的优先级计算逻辑。

例如,我们按数字从大到小的顺序排列优先级:

var jobs = new PriorityQueue<Job, int>(); jobs.Enqueue(new Job() { Id = 1 }, 100);
jobs.Enqueue(new Job() { Id = 2 }, 200);
jobs.Enqueue(new Job() { Id = 3 }, 300);while (jobs.TryDequeue(out var job,out var priority))
{Console.WriteLine(job.Id);
}public class JobComparer : IComparer<int>
{public int Compare(int x, int y){return y.CompareTo(x);}
}//输出
3
2
1

比较时机

那到底是放入队列时,还是从队列取出时进行比较呢?

我们用代码进行测试:

for (int i = 1; i <= 3; i++)
{Console.WriteLine($@"Enqueue {i}");jobs.Enqueue(new Job() { Id = i }, 100 * i);
}for (int i = 4; i <= 6; i++)
{Console.WriteLine($@"Enqueue {i}");jobs.Enqueue(new Job() { Id = i }, -100 * i);
}
for (int i = 7; i <= 9; i++)
{Console.WriteLine($@"Enqueue {i}");jobs.Enqueue(new Job() { Id = i }, 100 * i);
}Console.WriteLine("Dequeue");while (jobs.TryDequeue(out var job,out var priority))
{Console.WriteLine(job.Id);
}//输出
Enqueue 1
Enqueue 2
Compare(200, 100)
Enqueue 3
Compare(300, 200)
Enqueue 4
Compare(-400, 300)
Enqueue 5
Compare(-500, 300)
Enqueue 6
Compare(-600, 100)
Enqueue 7
Compare(700, 100)
Compare(700, 300)
Enqueue 8
Compare(800, 300)
Compare(800, 700)
Enqueue 9
Compare(900, 700)
Compare(900, 800)
Dequeue
Compare(200, 800)
Compare(-400, 800)
Compare(-500, 800)
Compare(700, 800)
Compare(100, -600)
Compare(300, 100)
Compare(700, 300)
9
Compare(200, 700)
Compare(-400, 700)
Compare(-500, 700)
Compare(300, 700)
Compare(100, -600)
Compare(300, 100)
8
Compare(200, 300)
Compare(-400, 300)
Compare(-500, 300)
Compare(100, 300)
Compare(100, -600)
7
Compare(200, 100)
Compare(-400, 200)
Compare(-500, 200)
Compare(-600, 200)
3
Compare(-600, 100)
Compare(-400, 100)
Compare(-500, 100)
2
Compare(-600, -500)
Compare(-400, -500)
1
Compare(-600, -500)
4
5
6

可以看到,放入和取出时都需要进行优先级比较。

放入时只和队列最顶部的元素进行比较,而取出时需要比较队列中所有剩余元素的优先级。

结论

通过上面的代码,可以发现PriorityQueue实际把队列中的元素分成了2堆:

Enqueue 8
Compare(800, 300)
Compare(800, 700)
Enqueue 9
Compare(900, 700)
Compare(900, 800)

你觉得这样做有什么目的?欢迎到公众号“My IO”上留言讨论!

.NET 6新特性试用 | PriorityQueue相关推荐

  1. .NET 6新特性试用 | 总结:我最喜欢的5个特性

    前言 不知不觉,<.NET 6新特性试用>系列文章已经写了20多篇,而今天终于要告一段落了. 如果你还没有看过,详细文章列表在这里: .NET 6新特性试用系列 在这么多特性中,我最喜欢如 ...

  2. .NET 6新特性试用 | 可空引用类型

    前言 在查看<隐式using指令>功能时,我们在csproj中发现这样一个属性: 那么,Nullable到底是干嘛的? 可为空上下文 严格来说,这不是新特性,而是C# 8.0引入的特性之一 ...

  3. 5.0 新特性试用体验之 Clustered Index

    作者:hzc989 原文来源: https://tidb.net/blog/69dd056c [是否原创]是 [首发渠道]TiDB 社区 [目录] 一.引言 二.基础前情回顾 三.era withou ...

  4. .NET 6新特性试用 | PeriodicTimer

    前言 在.NET中,已经存在了5个Timer类: System.Threading.Timer System.Timers.Timer System.Web.UI.Timer System.Windo ...

  5. .NET 6新特性试用 | 可写JSON DOM API

    前言 我们常用JSON的方式,是将类对象序列化/反序列化: var user = new User { Name = "My IO" }; var json = JsonSeria ...

  6. .NET 6新特性试用 | SDK工作负载

    前言 为了应对.NET SDK能够支持的程序集项目(例如iOS.Android.WASM)的不断增长,从.NET 6开始,允许用户仅安装必要的SDK(例如ASP.NET Core),而不是一次性安装& ...

  7. .NET 6新特性试用 | LINQ功能改进

    前言 .NET6为LINQ添加了多个新API,在本文中,我们将始终使用User类逐一演示这些添加到LINQ中的内容: public class User {public string Name { g ...

  8. .NET 6新特性试用 | ArgumentNullException卫语句

    前言 在前面的文章中(<可空引用类型>),我们介绍过编译器会帮我们检查空引用,但是仅仅是警告.最好的方式还是在运行时用卫语句进行检查: private void Test(WeatherF ...

  9. .NET 6新特性试用 | 热重载

    前言 在以前的开发模式下,我们修改代码后必须重新编译.重新运行才能看到效果. 而热重载提供了这样一种特性,它允许你在项目正在运行时修改代码,并将代码更改立即应用于正在运行的应用程序上. 热重载的目的是 ...

最新文章

  1. ,改变LI背景颜色与背景图片
  2. JAVA中常见的Exception
  3. python模块matplotlib.pyplot用法_python – 虽然使用pyplot.show(),但如何使用matplotlib保持图形大小不变?...
  4. 常用输入法隐藏的这些神奇功能
  5. c语言经典程序100txt例,C语言经典程序100例txt格式.doc
  6. java趣味题-打印杨辉三角
  7. Entity Framework 6.x - Code First 默认创建数据库的位置
  8. mongodb 导出一条数据_将 MongoDB 导出成 csv
  9. java环境变量设置 重启吗_java环境变量配置,原来是这样的
  10. LayaAir 事件 laya.events.Event
  11. java解析edi报文_EDI文件解析语法规则
  12. python登录qq定时发消息_python自动发送qq消息
  13. 国科大在线android版app,国科大心理app
  14. JAVA 导出大批量数据EXCEL
  15. 付费系列 6 - 离散型障碍和触碰期权 PDE 有限差分
  16. 读我们的学科——计算机专业学习浅谈
  17. 【概率论】5-5:负二项分布(The Negative Binomial Distribution)
  18. 打蚊子表情包_打蚊子表情包 - 打蚊子微信表情包 - 打蚊子QQ表情包 - 发表情 fabiaoqing.com...
  19. 在javascript中使用正则表达式来验证:E-Mail,账号,出生日期,姓名...
  20. 分布式搜索elasticsearch搜索功能【深入】

热门文章

  1. python 中的yum pip
  2. (转)svn检出的时候报 Unable to connect to a repository at URL错误
  3. ubuntun中文读书笔记
  4. 熊猫烧香是天才作品吗?
  5. 如何下载python2.7.16_CENTOS6.5 安装PYTHON2.7.16
  6. bash for循环_Bash 中的 For 循环
  7. 最全的正则表达式大全
  8. 【IntelliJ】IntelliJ IDEA常用设置及快捷键以及自定义Live templates
  9. npm 安装 chromedriver 失败的解决办法
  10. [luoguP2601] [ZJOI2009]对称的正方形(二维Hash + 二分 || Manacher)