[C#]关于Distinct与重写IEqualityComparer时得知道的二三事
我们在想对一个可枚举的对象集合进行去重操作时,一般第一个想到的就是就是Linq的Distinct方法。
先定义一个类,然后使用Distinct方法去重
class Man
{
public int Age { get; set; }
public string Name { get; set; }
public string Adress { get; set; }
public decimal Weight { get; set; }
public decimal Height { get; set; }
}
List<Man> list = new List<Man>()
{
new Man(){Age=,Name="Adam",Adress="Shenzhen",Weight=,Height=},
new Man(){Age=,Name="Adam",Adress="Shenzhen",Weight=,Height=}
};
var distinct = list.Distinct();
然而去重得到的distinct集合的Count依然为二,集合里依然存在两个Adam。
实际上,Distinct方法内进行比较的是声明的引用,而不是对象属性,就和对两个属性一模一样的对象使用Equals()方法得到的是False一样。
因此我们对对象集合使用Distinct方法时要使用重载Distinct<TSource>(this IEnumerable<TSource> source, IEqualityComparer<TSource> comparer);
要使用这个方法,我们得重写IEqualityComparer接口,再使用Distinct方法:
public class ManComparer : IEqualityComparer<Man>
{
public bool Equals(Man x, Man y)
{
return x.Age == y.Age
&& x.Name == y.Name
&& x.Adress == y.Adress
&& x.Weight == y.Weight
&& x.Height == y.Height;
} public int GetHashCode(Man obj)
{
return obj.GetHashCode();
}
} var distinct = list.Distinct(new ManComparer());
然而,再一次,distinct集合内依然有两个对象。
实际上,由于直接获取对象的HashCode,用HashCode进行比较的速度比 Equals 方法更快,
因此IEqualityComparer内部会在使用 Equals 前先使用 GetHashCode 方法,在两个对象的HashCode都相同时即刻判断对象相等。
而当两个对象HashCode不相同时, Equals 方法就会被调用,对要比较的对象进行判断。
由于在上例中list中的两个引用实际上是两个不同的对象,因此HashCode必定不相同
所以要触发Equlas方法,我们需要改 GetHashCode ,让它返回相同的常量
public class ManComparerNew : IEqualityComparer<Man>
{
public bool Equals(Man x, Man y)
{
return x.Age == y.Age
&& x.Name == y.Name
&& x.Adress == y.Adress
&& x.Weight == y.Weight
&& x.Height == y.Height;
} public int GetHashCode(Man obj)
{
return ;
}
} var distinct = list.Distinct(new ManComparerNew());
现在distinct集合中就只有一个Man对象了,成功实现了去重。
`
[C#]关于Distinct与重写IEqualityComparer时得知道的二三事的更多相关文章
- 为什么重写equals时必须重写hashCode方法?(转发+整理)
为什么重写equals时必须重写hashCode方法? 原文地址:http://www.cnblogs.com/shenliang123/archive/2012/04/16/2452206.html ...
- 讲解:为什么重写equals时必须重写hashCode方法
一 :string类型的==和equals的区别: 结论:"=="是判断两个字符串的内存地址是否相等,equals是比较两个字符串的值是否相等,具体就不做扩展了,有兴趣的同学可以去 ...
- Android Studio 重写方法时参数命名异常
Android Studio 重写方法时参数命名异常 Android Studio 重写方法时参数名称乱掉可以通过下载相应源码解决
- “全栈2019”Java异常第十一章:重写方法时只能抛出父类异常子集
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java异 ...
- Distinct删除重复数据时 自定义的方法比较【转】
最近项目中在用Linq Distinct想要将重复的资料去除时,发现它跟Any之类的方法有点不太一样,不能很直觉的在呼叫时直接带入重复数据判断的处理逻辑,所以当我们要用某个成员属性做重复数据的判断时, ...
- Linq使用Distinct删除重复数据时如何指定所要依据的成员属性zz
最近项目中在用Linq Distinct想要将重复的资料去除时,发现它跟Any之类的方法有点不太一样,不能很直觉的在呼叫时直接带入重复数据判断的处理逻辑,所以当我们要用某个成员属性做重复数据的判断时, ...
- java中为什么重写equals时必须重写hashCode方法?
在上一篇博文Java中equals和==的区别中介绍了Object类的equals方法,并且也介绍了我们可在重写equals方法,本章我们来说一下为什么重写equals方法的时候也要重写hashCod ...
- 为什么重写equals时必须重写hashCode方法?
原文地址:http://www.cnblogs.com/shenliang123/archive/2012/04/16/2452206.html 首先我们先来看下String类的源码:可以发现Stri ...
- 解决 Eclipse 重写方法时参数为arg0,arg1
我们在用eclipse 中Alt+ / 补全代码时.方法重写会出现arg0这样可读性差的参数. 原因是没有找到android 的源文件. 一.下载文件 需要下载 sources for android ...
随机推荐
- rem原理
rem布局实际上就是实现等比缩放 试想,如果我们的元素在不同的屏幕上可以按照相同的比例来进行缩放就好了. rem的计算原理: 试想把屏幕平均分成10份,那么每一份就是1/10,我们选择每一份的大小是1 ...
- SP16549 QTREE6 - Query on a tree VI LCT维护颜色联通块
\(\color{#0066ff}{ 题目描述 }\) 给你一棵n个点的树,编号1~n.每个点可以是黑色,可以是白色.初始时所有点都是黑色.下面有两种操作请你操作给我们看: 0 u:询问有多少个节点v ...
- P4196 [CQOI2006]凸多边形 半平面交
\(\color{#0066ff}{题目描述}\) 逆时针给出n个凸多边形的顶点坐标,求它们交的面积.例如n=2时,两个凸多边形如下图: 则相交部分的面积为5.233. \(\color{#0066f ...
- 通过div实现arcgis自定义infowindow
通过给地图绑定缩放,单击和平移命令,实现在地图附加div标签,实现infowindow效果: /* *作者 扰扰 *自定义esri弹窗 *paramter Map地图对象 *paramter x *p ...
- git ignore文件
创建.gitignore文件来设置git要忽略的文件模式: 官方文件列列表:https://github.com/github/gitignore 1. 所有空行或者以 # 开头的行都会被 Git 忽 ...
- pytorch搭建网络,保存参数,恢复参数
这是看过莫凡python的学习笔记. 搭建网络,两种方式 (1)建立Sequential对象 import torch net = torch.nn.Sequential( torch.nn.Line ...
- 在Ubuntu中使用AppImage类型文件
右键--属性---权限---允许作为执行文件启动
- Arm寄存器介绍及汇编基础
一.ARM处理器支持7种工作模式 ① 用户模式(USR): 用于正常执行程序(The normal ARM program execution state) ② 快速中断模式(FIQ): 用于高速数据 ...
- Java学习笔记day04_数组
1.switch case switch语句中表达式的数据类型是有要求的: JDK 1.0 ~ 1.4 , 数据类型接受byte, short, int, char JDK 1.5 , 数据类型接受b ...
- Error: Duplicate key name 'PCS_STATS_IDX' (state=42000,code=1061) ----Hive schematool -initSchema -dbType mysql
schematool -initSchema -dbType mysqlMetastore connection URL: jdbc:mysql://localhost/metastore_db?cr ...