4.8 反转Sorted List里的内容

问题

您希望在数组和列表类型中可以反转sorted list里的内容同时又维持SortedListSortedList<T>类原来的功能。无论是SortedList还是泛型SortedList<T>类都直接提供了完成这个功能的方法而又不需要重填列表。

解决方案

ReversibleSortedList<TKey, TValue>类提供了这些功能,它基于SortedList<TKey, TValue>类,所以拥有相同的功能,它提供了额外的功能是很容易反转已排序的列表。

在实例化ReversibleSortedList<TKey, TValue>之后,键是整数类型,值是字符串类型,一连串无序的数字和它们的文本表达被插入到列表中。这些项目是这样显示的:

C#泛型秘诀(5)ReversibleSortedList<intstring> rsl = new ReversibleSortedList<intstring>();
C#泛型秘诀(5)rsl.Add(
2"2");
C#泛型秘诀(5)rsl.Add(
5"5");
C#泛型秘诀(5)rsl.Add(
3"3");
C#泛型秘诀(5)rsl.Add(
1"1");
C#泛型秘诀(5)
foreach (KeyValuePair<intstring> kvp in rsl)
 

列表输出显示为按升序排序(默认):

    1   1

    2   2

    3   3

    5   5

现在排列顺序通过设置ReversibleSortedList的SortDirection属性被反转为降序。为了重新排序需要调用Sort()方法。结果如下:

C#泛型秘诀(5)// 转换排序方向.
C#泛型秘诀(5)
rsl.Comparer.SortDirection = ListSortDirection.Descending;
C#泛型秘诀(5)
// 重排列表.
C#泛型秘诀(5)
rsl.Sort();
C#泛型秘诀(5)
foreach (KeyValuePair<intstring> kvp in rsl)
 

这一次,输出为降序:

    5   5

    3   3

    2   2

1   1

当把一个新项添加进列表,它将按当前的排列顺序被添加进去,但在添加完所有项后马上进行反转,就可以保持列表中元素的顺序。

C#泛型秘诀(5)rsl.Add(4"4");
C#泛型秘诀(5)    
foreach (KeyValuePair<intstring> kvp in rsl)
 

可以看到新项即按降序也按升序排列:

    5   5

    4   4

    3   3

    2   2

    1   1

    1   1

    2   2

    3   3

    4   4

    5   5

 

ReversibleSortedList<TKey, TValue>包含一个实现了IComparer<T>接口的嵌套类SortDirectionComparer<T>。这个类可以在“讨论”这一节中的ReversibleSortedList<TKey, TValue>代码中看到。一个实现了IComparer<T>接口的类可以做为ReversibleSortedList<TKey, TValue>构造方法的参数来改变默认的排序。IComparer<T>接口实现了Compare方法:

C#泛型秘诀(5)class Program
 

Compare方法使用了SortDirectionComparer<T>类的SortDirection属性来决定项的排序。这个属性在ReversibleSortedList<TKey, TValue>的内部类SortDirectionComparer<T>实例中被设置。SortDirection属性是在构造方法中被设置的,代码如下:

C#泛型秘诀(5) public ReversibleSortedList()
 

这允许它在指定时间内反转排列顺序,但并没有重排列表中已存在的项。为了实现这个功能,需要在Reversible-SortedList<TKey, TValue>类中添加一个新的Sort()方法以重排列表。代码如下:

C#泛型秘诀(5)public void Sort()
 

讨论

4-3是ReversibleSortedList<TKey, TValue>类的所有代码:

(译者注:这个类的代码很恐怖,接近1300行,不过代码很规范,感觉应该是商业代码,非常值得借鉴。将来有时间我会专门写文章分析它。请关注:我的博客:http://cgbluesky.blog.163.com/)

4-3 ReversibleSortedList类

C#泛型秘诀(5)[Serializable, ComVisible(false), DebuggerDisplay("Count = {Count}")]
C#泛型秘诀(5)
public class ReversibleSortedList<TKey, TValue> :
C#泛型秘诀(5)        IDictionary
<TKey, TValue>, ICollection<KeyValuePair<TKey, TValue>>,
C#泛型秘诀(5)        IEnumerable
<KeyValuePair<TKey, TValue>>,
C#泛型秘诀(5)        IDictionary, ICollection, IEnumerable
 

SortedList混合使用了数组和列表语法,这使得以任一方式访问数据变得非常容易。ReversibleSortedList<T>中数据也可以使用键/值对或索引来访问。和SortedList一样,它不允许重复键。另外不管值是引用类型还是值类型都可以为null,但键不行。ReversibleSortedList<T>的默认容量是16,这和SortedList是一样的。里面的项可以使用foreach循环进行迭代,它返回KeyValuePair,但这是只读的,迭代语法禁止在读取列表时进行元素的更新或删除,否则就是无效的迭代器。

阅读参考

查看秘诀6.3MSDN文档中的“Generic KeyValuePairStructure”和“Generic SortedList”主题。



相关文章: