背景说明

在EF等ORM框架中需要以List实体类的方式对数据进行大量操作,其中免不了对一些数据进行去重复,而C#中IEnumerable.Distinct()便提供了这一功能。只是对刚开始接触的新人来说比价抽象难以接受,本文会对这一功能进行简要说明,如果有更好的实现方式,也请大家畅所语言。

在写本文时,本人也在网上搜索了很多相关资料,其中有几篇比较有参考价值,也是重点,本文也是基于这几篇文章提供的代码进行优化和整理:

1、用泛型委托实现IEqualityComparer接口:https://blog.csdn.net/honantic/article/details/51595823

2、Distinct的多条件查询:https://blog.csdn.net/lishuangquan1987/article/details/76096022

3、IEqualityComparer中的Equal()和GetHashCode():https://www.cnblogs.com/xiaochen-vip8/p/5506478.html

我们要做的是实现IEqualityComparer()接口,而且必须要用泛型,因为我们希望这个功能是可以对所有实体类实现的。其中对哈希值的了解可以参考第三条链接,可以简单的概括为,哈希值反应的是对象在内存中的地址,只有地址相同的对象才能激活IEqualityComparer中的Equal()方法,Equal()可以根据自己的需求而实现。话不多说,代码如下:

        /// <summary>/// 用委托实现IEqualityComparer<T>接口/// </summary>/// <typeparam name="T">目标类型</typeparam>public class ListComparer<T> : IEqualityComparer<T>{public Func<T, T, bool> EqualsFunc;public Func<T,int> GetHashCodeFunc;public ListComparer(Func<T,T,bool> Equals, Func<T,int> GetHashCode){this.EqualsFunc = Equals;this.GetHashCodeFunc = GetHashCode;}public ListComparer(Func<T, T, bool> Equals) : this(Equals, t => 0){}public bool Equals(T x, T y){if (this.EqualsFunc != null){return this.EqualsFunc(x, y);}else{return false;}}/// <summary>/// 获取目标对象的哈希值,只有返回相同的哈希值才能运行Equals方法/// </summary>/// <param name="obj">获取哈希值的目标类型对象</param>/// <returns>返回哈希值</returns>public int GetHashCode(T obj){if (this.GetHashCodeFunc != null){return this.GetHashCodeFunc(obj);}else{return 0;}}}

以上代码中,默认哈希值是相同的,我们开始看看使用效果,代码如下:

        static void Main(string[] args){List<Phone> PhoneLists = new List<Phone>(){new Phone { Country = "中国", City = "北京", Name = "小米" },new Phone { Country = "中国",City = "北京",Name = "华为"},new Phone { Country = "中国",City = "北京",Name = "联想"},new Phone { Country = "中国",City = "台北",Name = "魅族"},new Phone { Country = "日本",City = "东京",Name = "索尼"},new Phone { Country = "日本",City = "大阪",Name = "夏普"},new Phone { Country = "美国",City = "加州",Name = "苹果"},new Phone { Country = "美国",City = "华盛顿",Name = "三星"}};var Lists = PhoneLists.Distinct<Phone>();foreach (var list in Lists){Console.WriteLine(list.Country + "-" + list.City + "-" + list.Name);}Console.Read();}

在Distinct()方法没有任何参数的情况下,运行后如下图所示:

我们可以看到,好像并没有任何效果,但是其实是有效果的,因为每个Phone实体类对象在内存中的地址是不一样的,         Distinct()方法默认筛选出所有内存地址不一样的实体类对象。

接下去需求改变,我们希望得出总共有多少个不同的country,country相同的数据随便返回其中一个就行,代码如下所示:

        static void Main(string[] args){List<Phone> PhoneLists = new List<Phone>(){new Phone { Country = "中国", City = "北京", Name = "小米" },new Phone { Country = "中国",City = "北京",Name = "华为"},new Phone { Country = "中国",City = "北京",Name = "联想"},new Phone { Country = "中国",City = "台北",Name = "魅族"},new Phone { Country = "日本",City = "东京",Name = "索尼"},new Phone { Country = "日本",City = "大阪",Name = "夏普"},new Phone { Country = "美国",City = "加州",Name = "苹果"},new Phone { Country = "美国",City = "华盛顿",Name = "三星"}};var Lists2 = PhoneLists.Distinct<Phone>(new ListComparer<Phone>((x,y) => x.Country.Equals(y.Country)));foreach (var list in Lists){Console.WriteLine(list.Country + "-" + list.City + "-" + list.Name);}Console.Read();}

我们对country字段进行去重,得到的结果如下图所示:

再接下去,需求又变,我们要筛选出有多少不同的国家和城市,这意味着要对country和city两个字段进行去重,代码如下:

        static void Main(string[] args){List<Phone> PhoneLists = new List<Phone>(){new Phone { Country = "中国", City = "北京", Name = "小米" },new Phone { Country = "中国",City = "北京",Name = "华为"},new Phone { Country = "中国",City = "北京",Name = "联想"},new Phone { Country = "中国",City = "台北",Name = "魅族"},new Phone { Country = "日本",City = "东京",Name = "索尼"},new Phone { Country = "日本",City = "大阪",Name = "夏普"},new Phone { Country = "美国",City = "加州",Name = "苹果"},new Phone { Country = "美国",City = "华盛顿",Name = "三星"}};var Lists = PhoneLists.Distinct<Phone>(new ListComparer<Phone>((x, y) => x.Country.Equals(y.Country) && x.City.Equals(y.City)));foreach (var list in Lists){Console.WriteLine(list.Country + "-" + list.City + "-" + list.Name);}Console.Read();}

执行结果如下图所示:

可以看到,已经达到了多字段的去重复效果,即便遇到需要去重复多个字段也可以实现,以上为个人拙见。

C#中IEnumerableT.Distinct()将指定实体类对象用Lambda表达式实现多条件去重相关推荐

  1. JSON字符串转为指定实体类对象

    创建JsonStringToClass对象即可 package utils;import net.sf.json.JSONArray; import net.sf.json.JSONObject;im ...

  2. JSON串 转成 指定实体类对象( TypeReference<>() {} )

    1.JSON串 tsrData: {"code": 1005,"msg": "用户名存在重复","data": null ...

  3. C#利用反射将Datatable转化为指定实体类ListT

    背景介绍 在软件开发中肯定免不了和数据库打交道,我们对数据的增删改查最终会转化为SQL在数据库中执行.从SQLServer中查出数据一般有两种方式:一是ADO.NET直接写SQL语句从数据中查出数据, ...

  4. 传递实体类对象_Java I/O 流之对象流中的序列化和反序列化

    一.概念 当两个进程远程通信时,彼此可以发送各种类型的数据. 无论是何种类型的数据,都会以二进制序列的形式在网络上传送.比如,我们可以通过 http 协议发送字符串信息:我们也可以在网络上直接发送 J ...

  5. @NamedEntityGraphs --JPA按实体类对象参数中的字段排序问题得解决方法

    JPA按实体类对象参数中的字段排序问题得解决方法@Entity @Table(name="complaints") @NamedEntityGraphs({ @NamedEntit ...

  6. 对Spring Data JPA中的page对象下的content属性里的实体类对象转换为dto对象

    对Spring Data JPA中的page对象下的content属性里的实体类对象转换为dto对象. 刚开始试遍历content,进行转换,添加到新的list中,再set进去page.后来发现pag ...

  7. Map集合转换成实体类对象,实体类对象转换为map集合,互转工具类

    注 : 2019-06-16日 增加第六节 map与实体互转工具类,直接看第6节; 1.调用这个方法BeanMapUtils.mapToBean(),实现map集合转实体类对象; 注意: 这个方法转换 ...

  8. 将远程服务器获取的linkedhashMap对象转为实体类对象

    微服务中从其他服务获取过来的对象,本来传的是实体类对象 , 但是接受到的参数却是linkedhashMap类型的对象 , 如果强转成自定义的实体类型会报错,因此可以利用ObjectMapper转换. ...

  9. JSON字符串封装成Bean对象/JSON串反序列化成实体类对象/JSON字符串转换成Java对象

    文章目录 使用阿里巴巴的 JSON 使用 ObjectMapper JSON字段与实体类属性不一致 首先,我们建立一个实体类,这里简单定义了 name.sex.age 三个属性,以及 get.set. ...

最新文章

  1. Spring的一些资源
  2. pyqt QGridLayout示例
  3. C#调用淘宝API流程整理
  4. POJ2349二分+并查集,类似最小树的贪心
  5. 智力+贪心的过河问题
  6. The Zen of Python, by Tim Peters
  7. php与nginx整合
  8. JavaScript 标准参考教程-阅读总结(三)
  9. OpenJDK织机和结构化并发
  10. mysql中max_allowed_packet参数的配置方法(避免大数据写入或者更新失败)
  11. git github配置
  12. VC实现多格式图像的转换
  13. vector中resize()和reserve()区别
  14. matlab保存tif图片
  15. ArcGIS之栅格地图配准
  16. 蒸汽管道图纸符号_管道图形符号
  17. 谈google搜索引擎的使用
  18. 高斯日记python实现
  19. php的seeder是什么,使用Laravel框架的Seeder实现自动填充数据功能
  20. Android 拍摄(横 \ 竖屏)视频的懒人之路

热门文章

  1. js 实现网页显示倒计时
  2. svn: Can't convert string from 'UTF-8' to native
  3. C# 导出word文档及批量导出word文档(3)
  4. 系统起动时加载的过程
  5. FFmpeg 2.1 试用(新版支持HEVC,VP9)
  6. 微软sharepoint团队博客
  7. XenServer上启动虚拟机失败’The VDI is not available’的解决方法
  8. 用 toto 3分钟建轻量级博客
  9. (转载)简洁、明晰!数据库设计三大范式应用实例剖析
  10. Oracle tips