博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
对象的比较与排序(七):对泛型列表进行排序和搜索:Comparison<T>和Predicate<T>的应用...
阅读量:6549 次
发布时间:2019-06-24

本文共 4803 字,大约阅读时间需要 16 分钟。

前面说到,我们可以使用 IComparer<T> 和 IComparable<T> 接口比较两个对象,然后对该类型的对象列表排序。现在我们来介绍另两个委托可以来用排序和搜索列表

先总结一下前面的内容:

MSDN上List有如下的sort重载:

如果调用无参的sort()方法,那么要求集合中的元素要实现 System.IComparable 接口,否则此方法会抛出InvalidOperationException异常。

如果集合的元素没有实现IComparable接口,则可以调用Sort(IComparer<T>),这时我们要创建一个类实现IComparer接口作为比较器来完成排序。

或者更为简单些,不需要定义一个比较器,直接给sort方法提供一个用于"比较两对象”大小的方法即可---实现Comparison<T>委托。

可以参见另一日记:

 

一般情况下,给列表排序需要有一个方法来比较T类型的两个对象。要在列表中搜索,也需要一个方法来检查T类型的对象,看看它是否满足某个条件。定义这样的方法很简单,这里给出两个可以使用的泛型委托。

1. Comparision<T>  这个委托类型用于排序方法,其返回类型和参数是 int method(T object A , T objectB)

2.Predicate<T> 这个委托类型用于搜索方法,其返回类型和参数是 bool method(T targetObject).

可以定义任意个这样的方法,使用它们实现 List<T> 的搜索和排序方法。

 

 

定义一个Vector类

Vector类
public class Vector     {
public double? R = null; public double? Theta = null; public double? ThetaRadians {
get {
// Convert degrees to radians. return (Theta * Math.PI / 180.0); } } public Vector(double? r, double? theta) {
// Normalize. if (r < 0) {
r = -r; theta += 180; } theta = theta % 360; // Assign fields. R = r; Theta = theta; } public static Vector operator +(Vector op1, Vector op2) {
try {
// Get (x, y) coordinates for new vector. double newX = op1.R.Value * Math.Sin(op1.ThetaRadians.Value) + op2.R.Value * Math.Sin(op2.ThetaRadians.Value); double newY = op1.R.Value * Math.Cos(op1.ThetaRadians.Value) + op2.R.Value * Math.Cos(op2.ThetaRadians.Value); // Convert to (r, theta). double newR = Math.Sqrt(newX * newX + newY * newY); double newTheta = Math.Atan2(newX, newY) * 180.0 / Math.PI; // Return result. return new Vector(newR, newTheta); } catch {
// Return "null" vector. return new Vector(null, null); } } public static Vector operator -(Vector op1) {
return new Vector(-op1.R, op1.Theta); } public static Vector operator -(Vector op1, Vector op2) {
return op1 + (-op2); } public override string ToString() {
// Get string representation of coordinates. string rString = R.HasValue ? R.ToString() : "null"; string thetaString = Theta.HasValue ? Theta.ToString() : "null"; // Return (r, theta) string. return string.Format("({0}, {1})", rString, thetaString); } }

 

下面定义一个集合类 Vectors

集合类
public class Vectors : List
{
public Vectors() {
} public Vectors(IEnumerable
initialItems) {
foreach (Vector vector in initialItems) {
Add(vector); } } public string Sum() {
StringBuilder sb = new StringBuilder(); Vector currentPoint = new Vector(0.0, 0.0); sb.Append("origin"); foreach (Vector vector in this) {
sb.AppendFormat(" + {0}", vector); currentPoint += vector; } sb.AppendFormat(" = {0}", currentPoint); return sb.ToString(); } }

 

 

 

下面就是我们要定义的用于排序和搜索的方法。

View Code
public static class VectorDelegates     {
public static int Compare(Vector x, Vector y) {
if (x.R > y.R) {
return 1; } else if (x.R < y.R) {
return -1; } return 0; } public static bool TopRightQuadrant(Vector target) {
if (target.Theta >= 0.0 && target.Theta <= 90.0) {
return true; } else {
return false; } } }

上面的代码,  Compare用于比较,TopRightQuadrant用于搜索。

 

下面是测试代码。

测试代码
class Program     {
static void Main(string[] args) {
Vectors route = new Vectors(); route.Add(new Vector(2.0, 90.0)); route.Add(new Vector(1.0, 180.0)); route.Add(new Vector(0.5, 45.0)); route.Add(new Vector(2.5, 315.0)); Console.WriteLine(route.Sum()); Comparison
sorter = new Comparison
(VectorDelegates.Compare); route.Sort(sorter); Console.WriteLine(route.Sum()); Predicate
searcher = new Predicate
(VectorDelegates.TopRightQuadrant); Vectors topRightQuadrantRoute = new Vectors(route.FindAll(searcher)); Console.WriteLine(topRightQuadrantRoute.Sum()); Console.ReadKey(); } }

总结:

1、关于 Predicate<T> 更详细用法,参见

2、可以参见上一个日记,可以用Lamda表达式来使代码更简洁。

 

转载于:https://www.cnblogs.com/eagle1986/archive/2012/02/03/2285434.html

你可能感兴趣的文章
Mozilla公布Firefox 2011年开发计划
查看>>
Java访问类中private属性和方法
查看>>
UIImage扩展方法(Category)支持放大和旋转
查看>>
可复用的WPF或者Silverlight应用程序和组件设计(3)——控件级别
查看>>
hibernate的一些缺陷(转)
查看>>
An easy to use android color picker library
查看>>
忘记Django登陆账号和密码的处理方法
查看>>
C++的头文件和实现文件分别写什么
查看>>
C语言 · 学生信息(P1102)
查看>>
做项目,还是标准点好(对象命名标准),呵呵
查看>>
iOS开发学习笔记:使用xcode里的单元测试,放在STAssert…里面的语句无法使用自动完成功能...
查看>>
利用批处理文件和任务计划实现Oracle数据库的自动备份
查看>>
API开发 – 让异常变得优雅
查看>>
【270天】每日项目总结系列008(2017.11.02)
查看>>
记一次线上CPU超高的排查过程
查看>>
获取群成员邀请关系
查看>>
Ionic:livereload on iOS and android
查看>>
react day one 让陡峭的学习曲线平缓一点
查看>>
Coursera 的 GraphQL 之旅
查看>>
ldap服务简单部署
查看>>