引用

最近总有种感觉,自己复习的进度总被项目中的问题给耽搁了,项目中遇到的问题,不总结又不行,只能将复习基础方面的东西放后再放后。一直没研究过太深奥的东西,过去一年一直在基础上打转,写代码,反编译,不停的重复。一直相信,在你不知道要干嘛的时候,浮躁的时候,不如回到最基础的东西上,或许换种思考方式,会有不一样的收获。

泛型集合List<T>排序

先看一个简单的例子,int类型的集合:

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Wolfy.SortDemo
{
class Program
{
static void Main(string[] args)
{
List<int> list = new List<int>() { , , , -, -, , , };
Console.WriteLine("排序前....");
foreach (int item in list)
{
Console.Write(item+"\t");
}
list.Sort();
Console.WriteLine();
Console.WriteLine("排序后....");
foreach (int item in list)
{
Console.Write(item+"\t");
}
Console.Read();
}
}
}

经sort方法之后,采用了升序的方式进行排列的。

集合的Sort方法

  //
// 摘要:
// 使用默认比较器对整个 System.Collections.Generic.List<T> 中的元素进行排序。
//
// 异常:
// System.InvalidOperationException:
// 默认比较器 System.Collections.Generic.Comparer<T>.Default 找不到 T 类型的 System.IComparable<T>
// 泛型接口或 System.IComparable 接口的实现。
public void Sort();
//
// 摘要:
// 使用指定的 System.Comparison<T> 对整个 System.Collections.Generic.List<T> 中的元素进行排序。
//
// 参数:
// comparison:
// 比较元素时要使用的 System.Comparison<T>。
//
// 异常:
// System.ArgumentNullException:
// comparison 为 null。
//
// System.ArgumentException:
// 在排序过程中,comparison 的实现会导致错误。 例如,将某个项与其自身进行比较时,comparison 可能不返回 0。
public void Sort(Comparison<T> comparison);
//
// 摘要:
// 使用指定的比较器对整个 System.Collections.Generic.List<T> 中的元素进行排序。
//
// 参数:
// comparer:
// 比较元素时要使用的 System.Collections.Generic.IComparer<T> 实现,或者为 null,表示使用默认比较器 System.Collections.Generic.Comparer<T>.Default。
//
// 异常:
// System.InvalidOperationException:
// comparer 为 null,且默认比较器 System.Collections.Generic.Comparer<T>.Default 找不到
// T 类型的 System.IComparable<T> 泛型接口或 System.IComparable 接口的实现。
//
// System.ArgumentException:
// comparer 的实现导致排序时出现错误。 例如,将某个项与其自身进行比较时,comparer 可能不返回 0。
public void Sort(IComparer<T> comparer);
//
// 摘要:
// 使用指定的比较器对 System.Collections.Generic.List<T> 中某个范围内的元素进行排序。
//
// 参数:
// index:
// 要排序的范围的从零开始的起始索引。
//
// count:
// 要排序的范围的长度。
//
// comparer:
// 比较元素时要使用的 System.Collections.Generic.IComparer<T> 实现,或者为 null,表示使用默认比较器 System.Collections.Generic.Comparer<T>.Default。
//
// 异常:
// System.ArgumentOutOfRangeException:
// index 小于 0。 - 或 - count 小于 0。
//
// System.ArgumentException:
// index 和 count 未指定 System.Collections.Generic.List<T> 中的有效范围。 - 或 - comparer
// 的实现导致排序时出现错误。 例如,将某个项与其自身进行比较时,comparer 可能不返回 0。
//
// System.InvalidOperationException:
// comparer 为 null,且默认比较器 System.Collections.Generic.Comparer<T>.Default 找不到
// T 类型的 System.IComparable<T> 泛型接口或 System.IComparable 接口的实现。
public void Sort(int index, int count, IComparer<T> comparer);

Sort()

可见sort方法有三个重载方法。

对自定义类型排序

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Wolfy.SortDemo
{
public class Person
{
public string Name { set; get; }
public int Age { set; get; }
}
}

对Person进行sort后输出,就会出现如下异常:

对自定义的Person类型进行排序,出现异常。那为什么int类型就没有呢?可以反编译一下,你会发现:

可见int类型是实现了IComparable这个接口的。那么如果让自定义类型Person也可以排序,那么试试实现该接口。

修改Person类

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Wolfy.SortDemo
{
public class Person : IComparable
{
public string Name { set; get; }
public int Age { set; get; } /// <summary>
/// 实现接口中的方法
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public int CompareTo(object obj)
{
Person p = obj as Person;
//因为int32实现了接口IComparable,那么int也有CompareTo方法,直接调用该方法就行
return this.Age.CompareTo(p.Age);
}
}
}

CompareTo方法的参数为要与之进行比较的另一个同类型对象,返回值为int类型,如果返回值大于0,表示第一个对象大于第二个对象,如果返回值小于0,表示第一个对象小于第二个对象,如果返回0,则两个对象相等。
定义好默认比较规则后,就可以通过不带参数的Sort方法对集合进行排序。

测试结果:

以上采用的sort()方法排序的结果。

实际使用中,经常需要对集合按照多种不同规则进行排序,这就需要定义其他比较规则,可以在Compare方法中定义,该方法属于IComparer<T>泛型接口,请看下面的代码:

 namespace Wolfy.SortDemo
{
public class PersonNameDesc:IComparer<Person>
{
//存放排序器实例
public static PersonNameDesc NameDesc = new PersonNameDesc();
public int Compare(Person x, Person y)
{
return System.Collections.Comparer.Default.Compare(x.Name, y.Name);
}
}
}

Compare方法的参数为要进行比较的两个同类型对象,返回值为int类型,返回值处理规则与CompareTo方法相同。其中的Comparer.Default返回一个内置的Comparer对象,用于比较两个同类型对象。

下面用新定义的这个比较器对集合进行排序:

  class Program
{
static void Main(string[] args)
{
List<Person> list = new List<Person>()
{
new Person(){Name="a",Age=},
new Person(){Name="d",Age=},
new Person(){Name="b",Age=},
new Person(){Name="c",Age=}
}; list.Sort(PersonNameDesc.NameDesc);
foreach (Person p in list)
{
Console.WriteLine(p.Name + "\t" + p.Age);
}
Console.Read();
}
}

测试结果:

Sort(int index, int count, IComparer<T> comparer)

同上面的类似,只是这个是取范围的。

Sort(Comparison<T> comparison)

sort方法的一个重载是Comparison<T>类型的参数,那么Comparison到底是什么东东呢?,说实话,不F12还真发现不了。

 #region 程序集 mscorlib.dll, v4.0.0.0
// C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\mscorlib.dll
#endregion namespace System
{
// 摘要:
// 表示比较同一类型的两个对象的方法。
//
// 参数:
// x:
// 要比较的第一个对象。
//
// y:
// 要比较的第二个对象。
//
// 类型参数:
// T:
// 要比较的对象的类型。
//
// 返回结果:
// 一个有符号整数,指示 x 与 y 的相对值,如下表所示。 值 含义 小于 0 x 小于 y。 0 x 等于 y。 大于 0 x 大于 y。
public delegate int Comparison<in T>(T x, T y);
}

看到这里就该笑了,委托啊,那么岂不是可以匿名委托,岂不是更方便啊。那么排序可以这样了。

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Wolfy.SortDemo
{
class Program
{
static void Main(string[] args)
{
List<Person> list = new List<Person>()
{
new Person(){Name="a",Age=},
new Person(){Name="b",Age=},
new Person(){Name="c",Age=},
new Person(){Name="d",Age=}
};
//匿名委托
list.Sort((a,b)=>a.Age-b.Age);
foreach (Person p in list)
{
Console.WriteLine(p.Name + "\t" + p.Age);
}
Console.Read();
}
}
}

结果:

使用Linq排序

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Wolfy.SortDemo
{
class Program
{
static void Main(string[] args)
{
List<Person> list = new List<Person>()
{
new Person(){Name="a",Age=},
new Person(){Name="d",Age=},
new Person(){Name="b",Age=},
new Person(){Name="c",Age=}
};
var l = from p in list
orderby p.Age descending
select p;
//list.Sort(PersonNameDesc.NameDesc);
foreach (Person p in l)
{
Console.WriteLine(p.Name + "\t" + p.Age);
}
Console.Read();
}
}
}

总结

从下班弄到现在,一直整理笔记。泛型集合的排序选一个顺手的就行。

[c#基础]泛型集合的自定义类型排序的更多相关文章

  1. C# 泛型集合的自定义类型排序

    一.泛型集合List<T>排序 经sort方法之后,采用了升序的方式进行排列的. List<int> list = new List<int>() { 2, 4, ...

  2. Axis2Service客户端访问通用类集合List自定义类型

    Axis2 服务四种客户端调用方式: 1.AXIOMClient 2.generating a client using ADB 3.generating a client using XMLBean ...

  3. 泛型学习第三天——C#读取数据库返回泛型集合 把DataSet类型转换为List<T>泛型集合

    定义一个类: public class UserInfo    {        public System.Guid ID { get; set; } public string LoginName ...

  4. java:集合的自定义多重排序

    问题: 有一个乱序的对象集合,要求先按对象的属性A排序(排序规则由业务确定,非A-Z或0-9的常规顺序),相同A属性的记录,按根据属性B排序(排序规则,同样由业务确定,非常规顺序) -前提:业务规则是 ...

  5. MapReduce实战(二)自定义类型排序

    需求: 基于上一道题,我想将结果按照总流量的大小由大到小输出. 思考: 默认mapreduce是对key字符串按照字母进行排序的,而我们想任意排序,只需要把key设成一个类,再对该类写一个compar ...

  6. Java,集合按自定义规则排序

    import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.u ...

  7. java利用自定义类型对树形数据类型进行排序

    前言 为什么集合在存自定义类型时需要重写equals和hashCode? 1.先说List集合 List集合在存数据时是可以重复的但是 当我们需要判断一个对象是否在集合中存在时这样就有问题了! 因为我 ...

  8. golang 自定义类型的排序sort

    sort包中提供了很多排序算法,对自定义类型进行排序时,只需要实现sort的Interface即可,包括: func Len() int {... } func Swap(i, j int) {... ...

  9. HashSet存储自定义类型元素和LinkedHashSet集合

    HashSet集合存储自定义类型元素 HashSet存储自定义类型元素 set集合报错元素唯一: ~存储的元素(String,Integer,-Student,Person-)必须重写hashCode ...

随机推荐

  1. 使用jolokia api监控ActiveMQ

    jolokia api提供了一种通过HTTP访问JMX获得AMQ后台数据的一种方式,即Restful Api #!/usr/bin/env python # -*- coding:utf-8 -*- ...

  2. java并发编程实战笔记---(第三章)对象的共享

    3.1 可见性 synchronized 不仅实现了原子性操作或者确定了临界区,而且确保内存可见性. *****必须在同步中才能保证:当一个线程修改了对象状态之后,另一个线程可以看到发生的状态变化. ...

  3. Codeforces 445A Boredom(DP+单调队列优化)

    题目链接:http://codeforces.com/problemset/problem/455/A 题目大意:有n个数,每次可以选择删除一个值为x的数,然后值为x-1,x+1的数也都会被删除,你可 ...

  4. selenium webdriver操作各浏览器

    描述 本文主要是针对Chrome 62 , firefox57 ,和IE11 三个版本的操作.相关的driver .可点击以下链接.所有的driver 建议放在浏览器的目录下,本文中所有的driver ...

  5. bzoj 1854 并查集 + 贪心

    思路:这个题的并查集用的好NB啊, 我们把伤害看成图上的点,武器作为边,对于一个联通块来说, 如果是一棵大小为k的树,那么这个联通块里面有k - 1个伤害能被取到,如果图上有环那么k个值都能 取到,对 ...

  6. 500 多个 Linux 命令文档搜索

    500 多个 Linux 命令文档搜索 搜索界面:https://wangchujiang.com/linux-command/ 源码:https://github.com/jaywcjlove/li ...

  7. Vsftpd支持SSL加密传输

    ftp传输数据是明文,弄个抓包软件就可以通过数据包来分析到账号和密码,为了搭建一个安全性比较高ftp,可以结合SSL来解决问题   SSL(Secure Socket Layer)工作于传输层和应用程 ...

  8. 2017年浙江工业大学大学生程序设计迎新赛预赛 H - 栗酱的文明

    题目描述         “伟大的勇士兔栽栗女王,所有栗子看到您都不寒而栗,但也非常尊重您.您骑着威风凛凛的小白兔,带领兔栽栗们奋勇前行.伟大史诗告诉我们,烈兔勇栗从大草原飞奔出来,冲在每场战争的前线 ...

  9. Markdown 格式如何转换成 Word?

    参考资料:https://www.zhihu.com/question/22972843/answer/136008865 markdown语法简洁,写作效率极高,非常适合网络博客.邮件.笔记等非正式 ...

  10. NEO4j简单入门

    Neo4j是: 一个开源 无Schema 没有SQL 图形数据库 图形数据库也称为图形数据库管理系统或GDBMS. Neo4j的官方网站:http://www.neo4j.org Neo4j的优点 它 ...