Java 里用 Comparable 给对象排序,记住 compareTo 返回值规则就行
实现 Comparable 接口并重写 compareTo,就能用 Arrays.sort 对自定义对象排序,顺便聊聊几个容易踩的坑。
支持通配符SSL证书、多域名证书、IP证书。适配ACME接口, 支持Zerossl、Let's Encrypt和Google等渠道。登录已有账号
2026-09-13 04:01:08 C# Dictionary 排序
整理一下 C# 里 Dictionary 排序的几种做法。Dictionary 本身无序,这个不用多解释,但业务上按键或按值输出是常有的事。下面几个方式我都在项目里用过,代码可以直接跑。
LINQ 排序
最常用的就是 OrderBy 和 OrderByDescending。
写法简单,返回 IOrderedEnumerable,不是 Dictionary。遍历没问题,要拿集合结果得 ToList,要拿字典得 ToDictionary。适合一次性排序,排完就用。
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
Dictionary<int, string> fruits = new Dictionary<int, string>
{
{3, "Cherry"},
{1, "Apple"},
{5, "Elderberry"},
{2, "Banana"},
{4, "Date"}
};
var sortedByKey = fruits.OrderBy(kvp => kvp.Key);
Console.WriteLine("=== 按键升序 ===");
foreach (var item in sortedByKey)
Console.WriteLine($"[{item.Key}, {item.Value}]");
var sortedByValue = fruits.OrderBy(kvp => kvp.Value);
Console.WriteLine("\n=== 按值排序 ===");
foreach (var item in sortedByValue)
Console.WriteLine($"[{item.Key}, {item.Value}]");
}
}
这里 fruits 只有五项,看不出性能问题,数据量大一点还是尽量少在循环里反复 OrderBy。
List 转换排序
如果排序逻辑复杂,比如按值长度或者多字段,我习惯先 ToList 再 Sort。比较器随便写,不会影响原字典。List.Sort 是原地排序,复杂度 O(n log n)。
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
Dictionary<int, string> fruits = new Dictionary<int, string>
{
{3, "Cherry"},
{1, "Apple"},
{5, "Elderberry"}
};
List<KeyValuePair<int, string>> list = fruits.ToList();
list.Sort((a, b) => a.Key.CompareTo(b.Key));
Console.WriteLine("=== 列表排序结果 ===");
foreach (var item in list)
Console.WriteLine($"[{item.Key}, {item.Value}]");
}
}
一开始我也以为 List.Sort 会影响原字典,后来发现不会,因为 ToList 复制了一份 KeyValuePair 出来。
SortedDictionary 自动排序
SortedDictionary 是另一条路。它内部用红黑树维护键的顺序,插入和查找都是 O(log n)。
需要字典一直保持有序,而不是偶尔排一次,用它更合适。缺点是内存占用比 Dictionary 高,插入也慢。
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
Dictionary<int, string> fruits = new Dictionary<int, string>
{
{3, "Cherry"},
{1, "Apple"},
{5, "Elderberry"}
};
SortedDictionary<int, string> sortedDict = new SortedDictionary<int, string>(fruits);
Console.WriteLine("=== SortedDictionary结果 ===");
foreach (var kvp in sortedDict)
Console.WriteLine($"Key: {kvp.Key}, Value: {kvp.Value}");
}
}
拿 Dictionary 和 SortedDictionary 比,插入性能 Dictionary O(1),SortedDictionary O(log n);内存 Dictionary 低一些。但 Dictionary 无序,SortedDictionary 持续有序。如果你的写入远多于读取,还老是需要排序输出,SortedDictionary 不一定划算。
创建排序后新字典
还有一种做法是 OrderBy 之后直接 ToDictionary,生成一份有序的新字典。原字典不动,新字典可以继续用。注意键必须唯一,否则 ToDictionary 会抛 ArgumentException。
适合需要保留原字典、又想要一个有序副本的场景。
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
Dictionary<int, string> fruits = new Dictionary<int, string>
{
{3, "Cherry"},
{1, "Apple"},
{5, "Elderberry"}
};
var newSortedDict = fruits.OrderBy(kvp => kvp.Key)
.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
Console.WriteLine("=== 新有序字典 ===");
foreach (var kvp in newSortedDict)
Console.WriteLine($"Key: {kvp.Key}, Value: {kvp.Value}");
}
}
性能方面,一次性排序那几个,LINQ OrderBy、List.Sort、OrderBy + ToDictionary,时间复杂度都是 O(n log n),空间 O(n)。SortedDictionary 建好之后插入是 O(log n),但初始构造也是 O(n log n)。差别主要在后续维护成本。
实际选型我一般这样看。持续有序选 SortedDictionary;一次性输出用 OrderBy;复杂比较转 List.Sort;既要保留原字典又要有序副本,OrderBy + ToDictionary。
内存敏感的话少用链式 ToList 再 ToDictionary,中间会多出几份数据。
这里其实容易踩坑,有人觉得 Dictionary 遍历会按添加顺序,实际不是。要稳定输出就别依赖它。
环境相关的事也提一句。示例跑在本地无所谓,放到服务器上要做 HTTPS。
我一般用 lcjmSSL 自动申请证书,支持多域名、泛域名和 IP 证书,走 ACME 协议,能自动续期部署,不用自己记着每 90 天更新。省下来的时间可以多写两个排序测试。
实现 Comparable 接口并重写 compareTo,就能用 Arrays.sort 对自定义对象排序,顺便聊聊几个容易踩的坑。
一个C#开发者关于用TryParse和TryParseExact安全转换日期字符串的经验整理
本文深入浅出地讲解 C# 中 `File.Copy` 函数的核心用法。从语法解析到参数详解,再到实用示例,助你快速掌握文件复制操作。同时,我们还会提醒你如何避免文件覆盖、优雅处理异常以及规范路径格式,让你的代码更健壮。
还在为DataGridView显示长文本而烦恼?本文提供完整案例,教你如何通过设置WrapMode和AutoSizeRowsMode属性,轻松搞定单元格自动折行和行高自适应,并隐藏多余系统列,特别适合日志、消息展示,让你的数据视图整洁专业。
在C#开发中,处理日期字符串解析异常远不止简单捕获。本文聚焦于最佳实践与优化策略,深入探讨如何通过统一日期格式、利用TryParse家族方法进行防御性编程,以及运用正则表达式预校验来有效减少潜在异常。此外,我们还将讨论日志监控与用户输入验证的重要性,旨在提升系统对日期处理的鲁棒性,确保数据准确性,并显著改善用户体验。