集合去重

Posted JohnMarnoon

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了集合去重相关的知识,希望对你有一定的参考价值。

 用实现IEqualityComparer<T>接口的类,来进行重复元素的消除。

  class Program
    {
        static void Main(string[] args)
        {
           //集合去重
            //List<int> list = new List<int>() { 1,2,3,4,4,4,5,5,6};
            //list.Distinct().ToList().ForEach(s => Console.WriteLine(s)) ;
            Person p1 = new Person() { Name="兰陵王",Age=19};
            Person p2 = new Person() { Name="兰陵王",Age=19};
            Person p3 = new Person() { Name="亚瑟",Age=20};
            Person p4 = new Person() { Name="兰陵王",Age=29};
            Person p5 = new Person() { Name="王昭君",Age=21};
            Person p6 = new Person() { Name="王昭君",Age=21};

            Person p7 = new Person() { Name = "兰陵王", Age = 29 };
            Person p8 = new Person() { Name = "王昭君", Age = 22 };

            List<Person> list = new List<Person>() { p1,p2,p3,p4,p5,p6,p7,p8};
            //list.Distinct(new Compare()).ToList().ForEach(s => Console.WriteLine(s.ToString()));
            list.Distinct(new Compare<Person>()).ToList().ForEach(s => Console.WriteLine(s.ToString()));


            Console.ReadKey();
        }
        
    }
    public class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public override string ToString()
        {
            return string.Format("{0}\\t{1}", this.Name, this.Age);
        }
       
    }
   
    public class Compare : IEqualityComparer<Person>
    {
        
        public bool Equals(Person x, Person y)
        {
            bool b= (x.Name == y.Name)&&(x.Age==y.Age);
            return b;
        }
        public int GetHashCode(Person obj)
        {
            return obj.Name.GetHashCode();
        }
    }
    public class Compare<T> : IEqualityComparer<T>
    {
        public bool Equals(T x, T y)
        {
           PropertyInfo[]properties= x.GetType().GetProperties();
            bool mark = true;
            foreach (var property in properties)
            {
                mark = mark && property.GetValue(x).Equals(property.GetValue(y));   //不能用==
            }
            return mark;
        }
        public int GetHashCode(T obj)
        {
            PropertyInfo[] properties = obj.GetType().GetProperties();
            //return    properties[0].GetValue(obj).ToString().GetHashCode();
            //return (properties[0].GetValue(obj).ToString()+properties[1].GetValue(obj)).GetHashCode();
            //return obj.GetHashCode();
            int a = (properties[0].GetValue(obj).ToString() + properties[1].GetValue(obj)).GetHashCode();
            int b= obj.GetHashCode();//只要不是同一个对象,产生的HashCode就不一样(即使它所有属性都相同)。 
            return a;
        }
    }
    

 

 IEqualityComparer<T>接口的两个方法,一个Equals,一个GetHashCode,先用GetHashCode做第一遍过滤,如果HashCode就不一样,就不会剔除,也不会进行Equals方法。如有一样,再用Equals方法进行比较。
其实如果把对象的所有属性作为HashCode,Equals直接返回true就可以了 。
 
 

最后的版本
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data.SqlClient;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace sqlTest
{
    class Program
    {
        static void Main(string[] args)
        {
            //集合去重
            //List<int> list = new List<int>() { 1,2,3,4,4,4,5,5,6};
            //list.Distinct().ToList().ForEach(s => Console.WriteLine(s)) ;
            Person p1 = new Person() { Name = "兰陵王", Age = 19 };
            Person p2 = new Person() { Name = "兰陵王", Age = 19 };
            Person p3 = new Person() { Name = "亚瑟", Age = 20 };
            Person p4 = new Person() { Name = "兰陵王", Age = 29 };
            Person p5 = new Person() { Name = "王昭君", Age = 21 };
            Person p6 = new Person() { Name = "王昭君", Age = 21 };

            Person p7 = new Person() { Name = "兰陵王", Age = 29 };
            Person p8 = new Person() { Name = "王昭君", Age = 22 };

            List<Person> list = new List<Person>() { p1, p2, p3, p4, p5, p6, p7, p8 };
            //list.Distinct(new Compare()).ToList().ForEach(s => Console.WriteLine(s.ToString()));  //第一步
            // list.Distinct(new Compare<Person>()).ToList().ForEach(s => Console.WriteLine(s.ToString())); //第二步
            //最终版本
            list.MyDistinct((s => s.Name), (s => s.Age)).ToList().ForEach(s => Console.WriteLine(s.ToString()));

            Console.ReadKey();
        }

    }
    public class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public override string ToString()
        {
            return string.Format("{0}\\t{1}", this.Name, this.Age);
        }

    }





    #region 第一步
    //public class Compare : IEqualityComparer<Person>
    //{

    //    public bool Equals(Person x, Person y)
    //    {
    //        bool b = (x.Name == y.Name) && (x.Age == y.Age);
    //        return b;
    //    }
    //    public int GetHashCode(Person obj)
    //    {
    //        return obj.Name.GetHashCode();
    //    }
    //}
    #endregion

    #region 第二步
    //public class Compare<T> : IEqualityComparer<T>
    //{
    //    public bool Equals(T x, T y)
    //    {
    //        PropertyInfo[] properties = x.GetType().GetProperties();
    //        bool mark = true;
    //        foreach (var property in properties)
    //        {
    //            mark = mark && property.GetValue(x).Equals(property.GetValue(y));


    //        }
    //        return mark;

    //    }
    //    public int GetHashCode(T obj)
    //    {
    //        PropertyInfo[] properties = obj.GetType().GetProperties();
    //        //return    properties[0].GetValue(obj).ToString().GetHashCode();
    //        //return (properties[0].GetValue(obj).ToString()+properties[1].GetValue(obj)).GetHashCode();
    //        //return obj.GetHashCode();
    //        int a = (properties[0].GetValue(obj).ToString() + properties[1].GetValue(obj)).GetHashCode();
    //        int b = obj.GetHashCode();
    //        int c = properties[0].GetValue(obj).ToString().GetHashCode();
    //        int d = properties[0].GetValue(obj).GetHashCode();
    //        return c;
    //    }
    //}
    #endregion

    #region 最后的版本
    public static class CommonHelper
    {

        public static IEnumerable<T> MyDistinct<T, C, W>(this IEnumerable<T> source, Func<T, C> getfield, Func<T, W> getfield1)
        {
            return source.Distinct(new Compare<T, C, W>(getfield, getfield1));
        }
    }

    public class Compare<T, C, W> : IEqualityComparer<T>
    {
        private Func<T, C> _getField;
        private Func<T, W> _getField1;

        public Compare(Func<T, C> getfield, Func<T, W> _getField1)
        {
            this._getField = getfield;
            this._getField1 = _getField1;
        }
        public bool Equals(T x, T y)
        {
            return EqualityComparer<W>.Default.Equals(_getField1(x), _getField1(y));
        }
        public int GetHashCode(T obj)
        {
            return EqualityComparer<C>.Default.GetHashCode(this._getField(obj));
        }
    }
    #endregion

}

 

 

以上是关于集合去重的主要内容,如果未能解决你的问题,请参考以下文章

freemarker list集合去重,实现hashset

java使用Set集合去重

代码片段 - Golang 实现集合操作

laravel特殊功能代码片段集合

如何在List集合中去重

java对list集合进行去重 传统方式 VS Lambda