C#数组排序以及比较对象的大小
先来看个小例子吧
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#数组排序以及比较对象的大小的更多相关文章
- 如何精确地测量java对象的大小-底层instrument API
转载: 如何精确地测量java对象的大小-底层instrument API 关于java对象的大小测量,网上有很多例子,大多数是申请一个对象后开始做GC,后对比前后的大小,不过这样,虽然说这样测量对象 ...
- C++一个类对象的大小计算
计算一个类对象的大小时的规律: 1.空类.单一继承的空类.多重继承的空类所占空间大小为:1(字节,下同): 2.一个类中,虚函数本身.成员函数(包括静态与非静态)和静态数据成员都是不占用类对象的存储空 ...
- Ehcache计算Java对象内存大小
在EHCache中,可以设置maxBytesLocalHeap.maxBytesLocalOffHeap.maxBytesLocalDisk值,以控制Cache占用的内存.磁盘的大小(注:这里Off ...
- 计算Java对象内存大小
摘要 本文以如何计算Java对象占用内存大小为切入点,在讨论计算Java对象占用堆内存大小的方法的基础上,详细讨论了Java对象头格式并结合JDK源码对对象头中的协议字段做了介绍,涉及内存模型.锁原理 ...
- java 中对象比较大小
java 中对象比较大小 java 中对象比较大小有两种方法 1:实现Comparable 接口 的 public int compareTo(T o) 方法: 2:实现Comparator 接口 的 ...
- Java对象的大小及应用类型
基础类型数据的大小是固定的,对于非基本类型的java对象,其大小就值得商榷了. 在java中一个空Object对象的大小是8byte,这个大小只是保存堆中没有任何属性的对象的大小,看下面的语 ...
- C++类的实例化对象的大小之sizeof()
之所以写这篇<C++类的实例化对象的大小之sizeof()>.是由于在參加笔试的时候遇到例如以下这么一道题,当时感觉就是这个一个坑,但.我还是义无反顾的跳了下去,由于存在知识点盲区啊.现, ...
- 准确计算Java中对象的大小
由于在项目中需要大致计算一下对象的内存占用率(Hadoop中的Reduce端内存占用居高不下却又无法解释),因此深入学习了一下如何准确计算对象的大小. 使用system.gc()和java.lang. ...
- Java中计算对象的大小
一.计算对象大小的方法 Java中如何计算对象的大小呢,找到了4种方法: 1.java.lang.instrument.Instrumentation的getObjectSize方法: 2.BTrac ...
随机推荐
- mysql中的FROM_UNIXTIME()函数和UNIX_TIMESTAMP()函数
unix_timestamp 是时间戳,可以用数据库里的存储时间数据的字段 from_unixtime 是将时间戳格式化为你想要时间
- python3 练习题100例 (十三)
题目十三:将一个正整数分解质因数.例如:输入60,打印出60=2*2*3*5. #!/usr/bin/env python3 # -*- coding: utf-8 -*- ""& ...
- 饭卡 HDU - 2546(dp)
电子科大本部食堂的饭卡有一种很诡异的设计,即在购买之前判断余额.如果购买一个商品之前,卡上的剩余金额大于或等于5元,就一定可以购买成功(即使购买后卡上余额为负),否则无法购买(即使金额足够).所以大家 ...
- 相当牛X的java版星际游戏
分享一款牛人用java写的经典游戏,目录结构如下: 虽然只能算一个Demo,但是用到了很多Java基础技术和算法: Java2D,双缓冲,A星寻路,粒子系统,动画效果,处理图片,Swing ui ,U ...
- jsonp的原理及应用
https://blog.csdn.net/u011897301/article/details/52679486
- sqlserver 表值函数
一.单语句表值函数 ALTER function [dbo].[uf_get_jxc_da_sum](@dt char(8),@dt2 char(8)) RETURNS table as return ...
- MySql数据库 - 5.用C#连接数据库
添加 dll 引用,dll 位置:C:\Program Files (x86)\MySQL\Connector NET 8.0\Assemblies\v4.5.2 引入命名空间:MySql.Data. ...
- [Python]Pandas简单入门(转)
本篇文章转自 https://colab.research.google.com/notebooks/mlcc/intro_to_pandas.ipynb?hl=zh-cn#scrollTo=zCOn ...
- 【bzoj2836】魔法树 树链剖分+线段树
题目描述 输入 输出 样例输入 4 0 1 1 2 2 3 4 Add 1 3 1 Query 0 Query 1 Query 2 样例输出 3 3 2 题解 树剖+线段树模板题,不过为什么写的人这么 ...
- C# 泛型的入门理解(来自网络)
using System.Collections; class Program { //做个比较 static void Main(string[] args) { //new对象 Cls a1 = ...