我正在寻找一个能够将所有物品保持有序的容器。我查看了 SortedList,但这需要一个单独的键,并且不允许重复键。我也可以只使用一个未排序的容器,并在每次插入后对其进行显式排序。
用法:
- 偶尔插入
- 按顺序频繁遍历
- 理想情况下,不要使用与实际对象分开的键,使用比较函数进行排序。
- 需要对等效对象进行稳定排序,但不是必需的。
- 不需要随机访问。
我意识到我可以为自己构建一个平衡的树结构,我只是想知道框架是否已经包含这样一个野兽。
我正在寻找一个能够将所有物品保持有序的容器。我查看了 SortedList,但这需要一个单独的键,并且不允许重复键。我也可以只使用一个未排序的容器,并在每次插入后对其进行显式排序。
用法:
我意识到我可以为自己构建一个平衡的树结构,我只是想知道框架是否已经包含这样一个野兽。
您可能想看看Wintellect Power Collections。它在 CodePlex 上可用,并且包含很多非常有用的集合。项目中的 OrderedBag 集合正是您要寻找的。它本质上使用红黑树来提供非常有效的排序。
只是为了让EBarr 的评论SortedSet<T>
作为答案,从 .NET 4.0 开始就有了。当然它是一个集合,这意味着你不能有重复。
如果您只想坚持使用标准集合,那么该类的Sort(IComparer<>)
功能通常会被忽略。List<>
您需要做的就是创建一个适合Comparer<>
您的对象。例如:
public class PositionDateComparer : IComparer<VehiclePosition>
{
public int Compare(VehiclePosition x, VehiclePosition y)
{
if (x.DateTime == DateTime.MinValue)
{
if (y.DateTime == DateTime.MinValue)
{
// If x is null and y is null, they're
// equal.
return 0;
}
// If x is null and y is not null, y
// is greater.
return -1;
}
// If x is not null...
//
if (y.DateTime == DateTime.MinValue)
// ...and y is null, x is greater.
{
return 1;
}
// ...and y is not null, compare the dates
//
if (x.DateTime == y.DateTime)
{
// x and y are equal
return 0;
}
if (x.DateTime > y.DateTime)
{
// x is greater
return 1;
}
// y is greater
return -1;
}
}
vehiclePositionsList.Sort(new PositionDateComparer())
然后,只要您想在访问列表之前对列表进行排序,只需执行 a即可。我意识到这可能不像每次添加新对象时都会自动排序的容器那么简单,但对于许多人(比如我!)来说,这可能足以成功完成这项工作而无需任何额外的库。
正如您所提到的,我会扩展您自己的列表类,只需在每次插入后进行排序。由于您的插入不频繁,因此对性能的影响很小,并且无论如何对几乎排序的列表进行排序是很快的。扩展通用列表并覆盖 Add 方法以立即排序。如果性能成为问题,您可以插入到位以节省一些时间。此外,您可以对插入进行排队,以便对要插入的所有值进行一次遍历插入。
正如我今天早些时候在这里提到的,C5 通用集合库为您提供了合适的容器。
如果键也是对象的属性,您可以尝试使用System.Collections.ObjectModel.KeyedCollection<TKey, TItem>
. 它是一个抽象类,但如果您的密钥只是项目的一个属性,那么它的派生非常简单。
这是我在 VB6 中用来按字母顺序排序的一个老技巧:使用 System.Windows.Forms ListBox 对象,并将其“Sorted”属性设置为 true。在 C# 中,您可以将任何对象插入到列表框中,它会按对象的 ToString() 值按字母顺序对对象进行排序:
对于类模块:
使用 System.Windows.Forms;
static void Main(string[] args)
{
ListBox sortedList = new ListBox();
sortedList.Sorted = true;
sortedList.Items.Add("foo");
sortedList.Items.Add("bar");
sortedList.Items.Add(true);
sortedList.Items.Add(432);
foreach (object o in sortedList.Items)
{
Console.WriteLine(o);
}
Console.ReadKey();
}
这将显示:
第432
章
真