[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 ...
随机推荐
- 牛客寒假算法基础集训营1 D 小a与黄金街道
链接:https://ac.nowcoder.com/acm/contest/317/D 首先被数学题吓到了.gcd(n,x)==1 那么必定有 gcd(n,n-x)==1 证明略. 并且两个人的对答 ...
- 百度地图sdk使用
1.android开发百度地图定位,我怎么老是定到几内亚湾 权限问题,首先安卓6.0之后的Android的系统需要动态申请权限. 然后百度地图的sdk的不同功能,申请的权限不同,每个功能都需要看官方文 ...
- Entity Framework 更新带外键的实体为null
using (var ctx = new PortalContext()){ var city = ctx.Cities.Find(42); ctx.Entry(city) ...
- HDU 1565 方格取数(简单状态压缩DP)
http://acm.hdu.edu.cn/showproblem.php?pid=1565 对于每一个数,取或者不取,用0表示不取,1表示取,那么对于每一行的状态,就可以用一个二进制的数来表示.比如 ...
- day19 MRO C3算法 super()
1. MRO(Method Resolution Order):方法解析顺序,主要用于在多继承时判断调的属性的路径(来自于哪个类). 1.Python语言包含了很多优秀的特性,其中多重继承就是其中之一 ...
- 事务背书 ACID, CAP, BASE
A atomicity 原子性 一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成, C consistency 一致性 在事务开始之前和事务结束以后,数据库的完整性没有被破 ...
- Jmeter录制pc脚本
1.打开jmeter后可以看到左边窗口有个“测试计划”和“工作台”,右键“测试计划”,添加 Threads(Users) →线程组,再右键 线程组→添加 配置元件→Http请求默认值 Http请求默认 ...
- ECharts基本设置
theme = { // 全图默认背景 // backgroundColor: ‘rgba(0,0,0,0)’, // 默认色板 color: ['#ff7f50','#87cefa','#da70d ...
- 在windows上安装common lisp开发环境
(2014.1写于CSDN的文章) 最近对lisp非常感兴趣,因此在google中搜索了“common lisp install windows”, 想装一个开发环境玩玩. 第一条结果就是 “Gett ...
- vue router-link 添加在定义事件
在vue学习中遇到给router-link 标签添加事件@click .@mouseover等无效的情况 我想要做的是v-for遍历出来的选项卡, 鼠标移上去出现删除标签,移除标签消失的效果 原代码: ...