zoukankan      html  css  js  c++  java
  • list<T>.Sort()排序方法汇总

    近日,在工作的时候遇到要对一个大的List<T>集合进行排序,于是就了解下各种List<T>的排序方法。

    首先,排序自然就会想到用Sort方法,看看List<T>的Sort方法各个重载版本:

    public void Sort();
    public void Sort(Comparison<T> comparison);
    public void Sort(IComparer<T> comparer);
    public void Sort(int index, int count, IComparer<T> comparer);

    1:Sort()方法,摘要:使用默认比较器对整个 System.Collections.Generic.List<T> 中的元素进行排序,这里的默认比较器就是指Comparer<T>.Default。要使用默认比较器来排序,则类必须实现IComparable<T>接口,排序的时候会调用接口的CompareTo方法。

    接下来,就定义一个测试类Article,实现IComparable<Article>接口,排序先按SortIndex排序,再按Comments排序。类的定义如下:

    复制代码
    public class Article : IComparable<Article>
        {
            public string Title { get; set; }
            public int Comments { get; set; }
            public int SortIndex { get; set; }
    
            public override string ToString()
            {
                return string.Format("文章:{0},评论次数:{1}", this.Title, this.Comments);
            }
            
            public int CompareTo(Article other)
            {
                if (other == null)
                    return 1;
                int value = this.SortIndex - other.SortIndex;
                if (value == 0)
                    value = this.Comments - other.Comments;
                return value;
            }
        }
    复制代码

    定义一个获取100万的Article集合的方法,Article的SortIndex,Comments都是随机生成的。实现代码如下:

    复制代码
     private static List<Article> GetArticleList()
            {
                List<Article> source = new List<Article>();
                Article article = null;
                var random = new Random(DateTime.Now.Millisecond);
                for (int i = 1000000; i > 0; i--)
                {
                    article = new Article()
                    {
                        Title = "文章" + i.ToString(),
                        Comments = random.Next(),
                        SortIndex = random.Next()
                    };
                    source.Add(article);
                }
                return source;
            }
    复制代码

    执行Sort方法排序:

    private static void SortByDefaultComparer()
            {
                List<Article> list = GetArticleList();
                list.Sort();
            }

    2:使用Comparison委托

    Comparison委托的定义如下:public delegate int Comparison<in T>(T x, T y);

    使用委托,可以传递一个与委托签名相同的函数,可以使用匿名委托,还可以用Lambda表达式:

    首先使用第一种方法:定义一个ArticleComparison类,在里面定义一个Compare方法,函数签名与Comparison委托保持一致。实现代码如下:

    复制代码
    public class ArticleComparison
        {
            public int Compare(Article x, Article y)
            {
                if (x == null)
                {
                    if (y == null)
                        return 0;
                    else
                        return -1;
                }
                else
                {
                    if (y == null)
                    {
                        return 1;
                    }
                    else
                    {
                        int value = x.SortIndex.CompareTo(y.SortIndex);
                        if (value == 0)
                            value = x.Comments.CompareTo(y.Comments);
                        return value;
                    }
                }
            }
        }
    
    //方法调用
    private static void SortByComparison()
            {
                List<Article> list = GetArticleList();
                list.Sort(new Comparison<Article>(new ArticleComparison().Compare));
            }
    复制代码

    接下来,使用Lambda表达式,实现代码如下:

    复制代码
     private static void SortByLambda()
            {
                List<Article> list = GetArticleList();
                list.Sort((x, y) =>
                {
                    int value = x.SortIndex.CompareTo(y.SortIndex);
                    if (value == 0)
                        value = x.Comments.CompareTo(y.Comments);
                    return value;
                });
            }
    复制代码

    3:使用自定义的IComparer来排序,这里自定义一个ArticleCompare类:实现代码如下:

    复制代码
     public class ArticleCompare : IComparer<Article>
        {
            public int Compare(Article x, Article y)
            {
                if (x == null)
                {
                    if (y == null)
                        return 0;
                    else
                        return -1;
                }
                else
                {
                    if (y == null)
                    {
                        return 1;
                    }
                    else
                    {
                        int value = x.SortIndex.CompareTo(y.SortIndex);
                        if (value == 0)
                            value = x.Comments.CompareTo(y.Comments);
                        return value;
                    }
                }
            }
        }
    //方法调用
    private static void SortByCustomerComparer()
            {
                List<Article> list = GetArticleList();
                list.Sort(new ArticleCompare());
            }
    复制代码

    4:最后一个函数重载,就是指定对那些元素进行排序。

    小结:

    Sort<T>方法的各个重载版本,最终调用的都是Array.Sort<T>(T[] array, int index, int length, IComparer<T> comparer)方法。

    使用Comparison委托的时候,会执行IComparer<T> comparer = new Array.FunctorComparer<T>(comparison),最终转换为IComparer,因此在性能上会打点折扣。

    5:使用LINQ排序,实现代码如下:

    复制代码
    private static void SortByLinq()
            {
                List<Article> list = GetArticleList();
                var sortedList =
                   (from a in list
                    orderby a.SortIndex, a.Comments
                    select a).ToList();
            }
    复制代码

    6:使用扩展方法OrderBy,OrderByDescending,实现代码如下:

    private static void SortByExtensionMethod()
            {
                List<Article> list = GetArticleList();
                var sortedList = list.OrderBy(a => a.SortIndex).ThenBy(a => a.Comments);
     sortedList.ToList(); //这个时候会排序
    }

    疑惑:让我觉得奇怪的是,用扩展方法,排序的效率竟然会快的惊人。我看了扩展方法的实现如下:

    public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
    {
        return new OrderedEnumerable<TSource, TKey>(source, keySelector, null, false);
    }

    返回的是一个新的OrderedEnumerable<TSource, TKey>对象,OrderedEnumerable<>的构造方法如下:

    OrderedEnumerable(IEnumerable<TElement> source, Func<TElement, TKey> keySelector, IComparer<TKey> comparer, bool descending);

    看了实现代码,从常理来说是不可能快过Array.Sort<T>方法。只能留下疑惑。希望高人解答!

    此外,还有其他的排序方法,也请告知!

  • 相关阅读:
    convert image to base64 and post to RESTful wcf
    在android webview实现截屏的手动tounchmove裁剪图片
    How to use jquery ajax and android request security RESTful WCF
    using swfUpload in asp.net mvc
    using HttpClient and sending json data to RESTful server in adroind
    ODP.NET数据访问
    android image watermark
    解决国内不能访问github的问题
    idapro权威指南第二版阅读笔记第九章 交叉引用和绘图功能
    idapro权威指南第二版阅读笔记第二章 逆向和反汇编工具
  • 原文地址:https://www.cnblogs.com/zhisong/p/list.html
Copyright © 2011-2022 走看看