zoukankan      html  css  js  c++  java
  • C# List去重及优化建议

    简单例子-代码编写:

    首先创建实体:

       #region 公司
            public class Company
            {
                /// <summary>
                /// ID
                /// </summary>
                public int ID { get; set; }
                /// <summary>
                /// 公司名称
                /// </summary>
                public string CompanyName { get; set; }
                /// <summary>
                /// 地址
                /// </summary>
                public string Address { get; set; }
            } 
            #endregion

    实际操作

    static void Main(string[] args){
    List
    <Company> companys = new List<Company>();//公司实体Company,字段-公司名称,公司地址,电话 companys.Add(new Company() { ID = 1, CompanyName = "龙龙股份有限公司", Address = "固戍北辰路666号" }); companys.Add(new Company() { ID = 2, CompanyName = "龙龙股份有限公司", Address = "固戍放飞路三号" });//最后结果,重复项,此条数据删除 companys.Add(new Company() { ID = 3, CompanyName = "军军股份有限公司", Address = "固戍路甲八号" }); #region 方式一 //方式一:Lambda表达式去重 List<Company> companyList1 = companys.Where((x, i) => companys.FindIndex(z => z.CompanyName == x.CompanyName) == i).ToList(); #endregion #region 方式二 //方式二:List中的元素实现IEquatabe接口,并提供Equals方法和GetHashCode方法。 List<Company> companyList2 = companys.Distinct(new Dis()).ToList(); #endregion #region 方式三 //方式三:通过循环方式去重 List<Company> companyList3 = new List<Company>(); foreach (Company company in companys) { var isExists = companyList3.Exists(x => x.CompanyName == company.CompanyName);//是否存在相同数据 if (isExists == false) { companyList3.Add(company); } } #endregion

    //对比三种方式获取的数据就会知道一样的,第二条重复数据没有了。
    } #region Distinct筛选对比去重 /// <summary> /// Distinct筛选对比去重 /// </summary> public class Dis : IEqualityComparer<Company> { public bool Equals(Company x, Company y) { return x.CompanyName == y.CompanyName;//根据筛选的要求来判断 } public int GetHashCode(Company obj) { if (obj != null) { return obj.CompanyName.GetHashCode();//根据筛选的要求来判断 } return 0; } } #endregion

    提醒:IEqualityComparer<TSource> 定义了两个方法,一个是Equals,一个是GetHashCode。这里我查找参考资料发现,进行比较时,默认先通过GetHashCode对两个元素进行比较,如果HashCode不同,则认为两个元素不同,如果相同则再通过Equals方法比较。所以这里我不能直接将Company对象GetHashCode处理,而是先转换成了字符串再GetHashCode。通过这个重载方法,我们就可以到达目的了;

    方法二中Distinct 扩展:

    1.Distinct方法不加参数的话,去重的规则是比较对象集合中对象的引用是否相同,如果相同,则去重,否则不去重。

    2.Distinct方法加参数的话,我们需建一个类继承IEqualityComparer接口必须实现Equals和GetHashCode方法,然后在类里面根据自己的需求条件来写相关的判断。我们要向灵活可以优化封装一下。

    代码如下

      #region 封装Distinct去重
            /// <summary>
            /// 封装Distinct去重
            /// </summary>
            /// <typeparam name="T"></typeparam>
            public class LambdaComparer<T> : IEqualityComparer<T>
            {
                private readonly Func<T, T, bool> _lambdaEquals;//相等
                private readonly Func<T, int> _lambdaHash;//哈希
                public LambdaComparer(Func<T, T, bool> lambdaEquals)
                    : this(lambdaEquals, EqualityComparer<T>.Default.GetHashCode)
                {
                }
                public LambdaComparer(Func<T, T, bool> lambdaEquals, Func<T, int> lambdaHash)
                {
                    if (lambdaEquals == null)
                        throw new ArgumentNullException("lambdaEquals");//引发异常名称
                    if (lambdaHash == null)
                        throw new ArgumentNullException("lambdaHash");//引发异常名称
                    _lambdaEquals = lambdaEquals;
                    _lambdaHash = lambdaHash;
                }
              
                /// <summary>
                /// 是否相等
                /// </summary>
                /// <param name="x">X</param>
                /// <param name="y">Y</param>
                /// <returns></returns>
                public bool Equals(T x, T y)
                {
                    return _lambdaEquals(x, y);
                }
                /// <summary>
                /// 获取哈希码
                /// </summary>
                /// <param name="obj">obj</param>
                /// <returns></returns>
                public int GetHashCode(T obj)
                {
                    return _lambdaHash(obj);
                }
            }
            #endregion

    上面很好的利用了泛型委托的方式。下面我们想怎么比较就怎么比较了:

                List<Company> companyList2 = companys.Distinct(new LambdaComparer<Company>((x, y) => x.CompanyName == y.CompanyName, obj => obj.ToString().GetHashCode())).ToList();
               //List<Company> companyList2 = companys.Distinct(new LambdaComparer<Company>((a, b) => a.CompanyName == b.CompanyName && a.ID == b.ID, obj => obj.ToString().GetHashCode())).ToList();//可多个条件

    Distinct参考资料:

    1.https://www.cnblogs.com/cloudcmm/p/10975291.html

  • 相关阅读:
    Android核心分析 ---- 电话系统之GSMCallTacker
    Android核心分析 ----- Android电话系统之RIL-Java
    Android核心分析 ------ 电话系统之rilD
    Android核心分析 ----- Android电话系统-概述篇
    AndroidRuntime 流程
    关于++和--运算符的理解
    使用eclips开发java时的闪退问题
    Android--控件的滑动事件
    Running Hero.
    软件工程第三次大作业分工说明
  • 原文地址:https://www.cnblogs.com/yueyongsheng/p/12172835.html
Copyright © 2011-2022 走看看