我们在想对一个可枚举的对象集合进行去重操作时,一般第一个想到的就是就是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时得知道的二三事的更多相关文章

  1. 为什么重写equals时必须重写hashCode方法?(转发+整理)

    为什么重写equals时必须重写hashCode方法? 原文地址:http://www.cnblogs.com/shenliang123/archive/2012/04/16/2452206.html ...

  2. 讲解:为什么重写equals时必须重写hashCode方法

    一 :string类型的==和equals的区别: 结论:"=="是判断两个字符串的内存地址是否相等,equals是比较两个字符串的值是否相等,具体就不做扩展了,有兴趣的同学可以去 ...

  3. Android Studio 重写方法时参数命名异常

    Android Studio 重写方法时参数命名异常 Android Studio 重写方法时参数名称乱掉可以通过下载相应源码解决

  4. “全栈2019”Java异常第十一章:重写方法时只能抛出父类异常子集

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java异 ...

  5. Distinct删除重复数据时 自定义的方法比较【转】

    最近项目中在用Linq Distinct想要将重复的资料去除时,发现它跟Any之类的方法有点不太一样,不能很直觉的在呼叫时直接带入重复数据判断的处理逻辑,所以当我们要用某个成员属性做重复数据的判断时, ...

  6. Linq使用Distinct删除重复数据时如何指定所要依据的成员属性zz

    最近项目中在用Linq Distinct想要将重复的资料去除时,发现它跟Any之类的方法有点不太一样,不能很直觉的在呼叫时直接带入重复数据判断的处理逻辑,所以当我们要用某个成员属性做重复数据的判断时, ...

  7. java中为什么重写equals时必须重写hashCode方法?

    在上一篇博文Java中equals和==的区别中介绍了Object类的equals方法,并且也介绍了我们可在重写equals方法,本章我们来说一下为什么重写equals方法的时候也要重写hashCod ...

  8. 为什么重写equals时必须重写hashCode方法?

    原文地址:http://www.cnblogs.com/shenliang123/archive/2012/04/16/2452206.html 首先我们先来看下String类的源码:可以发现Stri ...

  9. 解决 Eclipse 重写方法时参数为arg0,arg1

    我们在用eclipse 中Alt+ / 补全代码时.方法重写会出现arg0这样可读性差的参数. 原因是没有找到android 的源文件. 一.下载文件 需要下载 sources for android ...

随机推荐

  1. jvm与tomcat启动优化配置

    JVM 优化 Java 的内存模型分为: Young,年轻代(易被 GC).Young 区被划分为三部分,Eden 区和两个大小严格相同的 Survivor 区,其中 Survivor 区间中,某一时 ...

  2. libxml2 安装及使用

    https://gitlab.gnome.org/GNOME/libxml2/ ftp://xmlsoft.org/libxml2/libxml2-2.9.1.tar.gz /configuremak ...

  3. 利用JPanel和JLabel设置背景图片

    //创建面板1,放置背景图片1 JPanel jPanelTop=new JPanel(); jPanelTop.setBounds(,-,,); //x=0,y=-5用来设置面板距离窗体左上角的距离 ...

  4. FileWriter 中午乱码

      解决办法 BufferedWriter writer = new BufferedWriter (new OutputStreamWriter (new FileOutputStream (fil ...

  5. Codeforces Round #335 (Div. 2) B

    B. Testing Robots time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...

  6. hive 取两次记录的时间差 lead lag first_value last_value

    -- LEAD(col,n,DEFAULT) 用于统计窗口内往下第n行值 -- 第一个参数为列名,第二个参数为往下第n行(可选,默认为1),第三个参数为默认值(当往下第n行为NULL时候,取默认值,如 ...

  7. 对称加密中的ECB模式&CBC模式

    ECB模式: CBC模式: 所有的迭代模式:

  8. python模块之wordcloud

    wordcloud官方文档: http://amueller.github.io/word_cloud/generated/wordcloud.WordCloud.html#wordcloud.Wor ...

  9. Juniper SRX550防火墙web页面CPU达到100%的故障解决办法

    Juniper SRX550防火墙web页面CPU达到100%的故障解决办法 利用telnet远程连接主机,对web页面注销重新登录即可,在配置中输入命令:run restart web-manage ...

  10. 页面中使用多个element-ui upload上传组件时绑定对应元素

    elemet-ui里提供的upload文件上传组件,功能很强大,能满足单独使用的需求,但是有时候会存在多次复用上传组件的需求,如下图的样子,这时候就出现了问题,页面上有多个上传组件时,要怎么操作呢? ...