先来看个小例子吧

int[] intArray = new int[]{,,,,,};
Array.Sort(intArray);
Array.ForEach<int>(intArray,(i)=>Console.WriteLine(i));

这个例子定义了一个int数组,然后使用Array.Sort(arr)静态方法对此数组进行排序,最后输出排序后的数组。以上例子将毫无意外的依次输出1,2,3,4,5,6.

为什么Array的Sort方法可以正确的对int数组进行排序呢,我们自定义类可以吗?试试看,如下代码:

public class Student
{
public int Age { get; set; } public string Name { get; set; } public int Score { get; set; }
} static void Main(string[] args)
{
Student[] students = new Student[]{
new Student(){Age = ,Name="张三",Score=},
new Student(){Age = ,Name="李四",Score=},
new Student(){Age = ,Name="王五",Score=},
new Student(){Age = ,Name="赵六",Score=},
new Student(){Age = ,Name="司马",Score=},
}; Console.WriteLine("--------------默认排序输出--------");
Array.Sort(students);
Array.ForEach<Student>(students,(s)=>Console.WriteLine(string.Format("{0}{1,2}岁了,他的分数是{2,3}",s.Name,s.Age,s.Score))); Console.Read();
}

我们定义了Student类然后同样对他的数组进行排序,程序正确的编译通过,但是运行出错,运行时抛出了异常:System.InvalidOperationException{"Failed to compare two elements in the array."},这个异常的InnerException是ArgumentException{"At least one object must implement IComparable."};运行时异常说明:我们要使用Array.Sort(arr)静态方法,必须得保证数组中有一个元素实现IComparable接口。既然如此我们就让Student类实现IComparable接口.

public class Student :IComparable
{
public int Age { get; set; } public string Name { get; set; } public int Score { get; set; } /// <summary>
/// 实现IComparable接口,用Age做比较
/// </summary>
/// <param name="obj">比较对象</param>
/// <returns>比较结果</returns>
public int CompareTo(object obj)
{
if (obj is Student)
{
return Age.CompareTo(((Student)obj).Age);
} return ;
}
}

在Student类中实现了IComparable接口,在CompareTo方法中比较Student的Age属性,这一次再次编译运行,程序正常的输出了按照年龄排序的Student数组。

假如说我们要对Student的Score属性进行排序该怎么办呢? Student类实现的IComparable接口只能按照一种属性排序呀。

这个是很容易实现的.net的类库开发者早为我们准备了另一个接口IComparer<T>接口用来实现比较类型T的两个实例。如下StudentScoreComparer类实现了对Student按照Score属性比较的IComparer<Student>

public class StudentScoreComparer : IComparer<Student>
{
public int Compare(Student x, Student y)
{
return x.Score.CompareTo(y.Score);
}
}

现在我们可以使用下面代码对Student数组按照Score属性进行排序:

Array.Sort(students, new StudentScoreComparer());
Array.ForEach<Student>(students, (s) => Console.WriteLine(string.Format("{0}{1,2}岁了,他的分数是{2,3}", s.Name, s.Age, s.Score)));

不过一个简单的按照Score属性排序,再定义一个类是不是有点大题小作呀,有没有更好的办法呢?当然有. .net为我们准备了比较对象大小的委托Comparison<T>我们可以使用拉姆达表达式或者匿名委托直接排序,如下代码实现:

Array.Sort(students, (s1, s2) => s1.Score.CompareTo(s2.Score));
Array.ForEach<Student>(students, (s) => Console.WriteLine(string.Format("{0}{1,2}岁了,他的分数是{2,3}", s.Name, s.Age, s.Score)));

完整代码示例如下:

using System.Collections.Generic;
using System.Linq;
using System.Text; namespace SortingInCSharp
{
class Program
{
public class Student : IComparable
{
public int Age { get; set; } public string Name { get; set; } public int Score { get; set; } /// <summary>
/// 实现IComparable接口,用Age做比较
/// </summary>
/// <param name="obj">比较对象</param>
/// <returns>比较结果</returns>
public int CompareTo(object obj)
{
if (obj is Student)
{
return Age.CompareTo(((Student)obj).Age);
} return ;
}
} static void Main(string[] args)
{
Student[] students = new Student[]{
new Student(){Age = ,Name="张三",Score=},
new Student(){Age = ,Name="李四",Score=},
new Student(){Age = ,Name="王五",Score=},
new Student(){Age = ,Name="赵六",Score=},
new Student(){Age = ,Name="司马",Score=},
}; Console.WriteLine("--------------默认排序输出--------");
Array.Sort(students);
Array.ForEach<Student>(students, (s) => Console.WriteLine(string.Format("{0}{1,2}岁了,他的分数是{2,3}", s.Name, s.Age, s.Score))); Console.WriteLine("----------按分数排序输出------------");
Array.Sort(students, new StudentScoreComparer());
Array.ForEach<Student>(students, (s) => Console.WriteLine(string.Format("{0}{1,2}岁了,他的分数是{2,3}", s.Name, s.Age, s.Score))); Console.WriteLine("----------按分数排序输出----------");
Array.Sort(students, (s1, s2) => s1.Score.CompareTo(s2.Score));
Array.ForEach<Student>(students, (s) => Console.WriteLine(string.Format("{0}{1,2}岁了,他的分数是{2,3}", s.Name, s.Age, s.Score))); Console.Read();
} public class StudentScoreComparer : IComparer<Student>
{
public int Compare(Student x, Student y)
{
return x.Score.CompareTo(y.Score);
}
}
}
}

总结:

在C#中有三个关于比较对象大小的接口,分别是IComparable、IComparable<T>和IComparer<T>。 IComparable和IComparable<T>是类本身实现的在实例之间比较大小的行为定义。IComparer<T>是定义在被比较类之外的专门比较两个T类型对象大小的行为,另外还有一个用于比较的委托定义Comparison<T>可以让我们用拉姆达表达式或者匿名委托或方法更方便的排序。

C#数组排序以及比较对象的大小的更多相关文章

  1. 如何精确地测量java对象的大小-底层instrument API

    转载: 如何精确地测量java对象的大小-底层instrument API 关于java对象的大小测量,网上有很多例子,大多数是申请一个对象后开始做GC,后对比前后的大小,不过这样,虽然说这样测量对象 ...

  2. C++一个类对象的大小计算

    计算一个类对象的大小时的规律: 1.空类.单一继承的空类.多重继承的空类所占空间大小为:1(字节,下同): 2.一个类中,虚函数本身.成员函数(包括静态与非静态)和静态数据成员都是不占用类对象的存储空 ...

  3. Ehcache计算Java对象内存大小

    在EHCache中,可以设置maxBytesLocalHeap.maxBytesLocalOffHeap.maxBytesLocalDisk值,以控制Cache占用的内存.磁盘的大小(注:这里Off ...

  4. 计算Java对象内存大小

    摘要 本文以如何计算Java对象占用内存大小为切入点,在讨论计算Java对象占用堆内存大小的方法的基础上,详细讨论了Java对象头格式并结合JDK源码对对象头中的协议字段做了介绍,涉及内存模型.锁原理 ...

  5. java 中对象比较大小

    java 中对象比较大小 java 中对象比较大小有两种方法 1:实现Comparable 接口 的 public int compareTo(T o) 方法: 2:实现Comparator 接口 的 ...

  6. Java对象的大小及应用类型

    基础类型数据的大小是固定的,对于非基本类型的java对象,其大小就值得商榷了.      在java中一个空Object对象的大小是8byte,这个大小只是保存堆中没有任何属性的对象的大小,看下面的语 ...

  7. C++类的实例化对象的大小之sizeof()

    之所以写这篇<C++类的实例化对象的大小之sizeof()>.是由于在參加笔试的时候遇到例如以下这么一道题,当时感觉就是这个一个坑,但.我还是义无反顾的跳了下去,由于存在知识点盲区啊.现, ...

  8. 准确计算Java中对象的大小

    由于在项目中需要大致计算一下对象的内存占用率(Hadoop中的Reduce端内存占用居高不下却又无法解释),因此深入学习了一下如何准确计算对象的大小. 使用system.gc()和java.lang. ...

  9. Java中计算对象的大小

    一.计算对象大小的方法 Java中如何计算对象的大小呢,找到了4种方法: 1.java.lang.instrument.Instrumentation的getObjectSize方法: 2.BTrac ...

随机推荐

  1. vue购物车的实现

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. Nosql和RDBMS的比较及解释

    概述 传统的关系型数据库以及数据仓库在面对大数据的处理时显得越来越力不从心.因为关系数据库管理系统 (RDBMS)的设计从未考虑过能够处理日益增长且格式多变的数据,以及访问数据并进行分析的用户需求呈爆 ...

  3. Paul Zindel【保罗·金代尔】

    Paul Zindel Paul Zindel's death on March 27, 2003 ended the brilliant life of a famous write. 2003年3 ...

  4. n个人排队都不站在原来的位置

    一.题目描述 有n个人首先站成一排,请问,当n个人第二次再重新排列,每个人都不在原来的位置上,问有多少种站法.例如,原来有3个人,ABC,那么第二次每个人都不在原来的位置上有2种站法,BCA和CAB, ...

  5. 手机端sticker布局,底部按钮在屏幕底部

    <template> <div class="product-detail-container"> <div class="detail&q ...

  6. va_list

    void Log( const TCHAR *pszFormat, ... ) { TCHAR buf[] ; va_list arglist ; try { _tcscpy_s ( buf, , _ ...

  7. 【Jump Game】cpp

    题目: Given an array of non-negative integers, you are initially positioned at the first index of the ...

  8. JWT实现token认证

    演变 1.1 有状态服务 在原来的单体系统中,有状态服务,即服务端需要记录每次会话的客户端信息,从而识别客户端身份,根据用户身份进行请求的处理,session+cookie.在如今的大多数分布式系统中 ...

  9. Leetcode 507.完美数

    完美数 对于一个 正整数,如果它和除了它自身以外的所有正因子之和相等,我们称它为"完美数". 给定一个 正整数 n, 如果他是完美数,返回 True,否则返回 False 示例: ...

  10. caffe工程配置问题

    一开始是碰到没有caffe/caffe.hpp文件的问题,不知道怎么弄.通过百度,知道了在makefile文件里加入头文件路径和库文件路径就行. 首先是caffe.pb.h丢失问题,解决方法:http ...