zoukankan      html  css  js  c++  java
  • C#中Equals和GetHashCode

    Equals和GetHashCode

    Equals每个实现都必须遵循以下约定:

    • 自反性(Reflexive): x.equals(x)必须返回true.
    • 对称性(Symmetric): x.equals(y)为true时,y.equals(x)也为true.
    • 传递性(Transitive): 对于任何非null的应用值x,y和z,如果x.equals(y)返回true,并且y.equals(z)也返回true,那么x.equals(z)必须返回true.
    • 一致性(Consistence): 如果多次将对象与另一个对象比较,结果始终相同.只要未修改x和y的应用对象,x.equals(y)连续调用x.equals(y)返回相同的值l.
    • 非null(Non-null): 如果x不是null,y为null,则x.equals(y)必须为false

    GetHashCode:

    • 两个相等对象根据equals方法比较时相等,那么这两个对象中任意一个对象的hashcode方法都必须产生同样的整数。
    • 在我们未对对象进行修改时,多次调用hashcode使用返回同一个整数.在同一个应用程序中多次执行,每次执行返回的整数可以不一致.
    • 如果两个对象根据equals方法比较不相等时,那么调用这两个对象中任意一个对象的hashcode方法,不一同的整数。但不同的对象,产生不同整数,有可能提高散列表的性能.

    IEqualityComparer实现

    下面我们创建一个学生类,从而进一步的实现我们对象数据的对比

        public class Student
        {
            public string Name { get; set; }
    
            public int Age { get; set; }
        }
    

    通过如下代码我们将通过distinct方法实现我们的过滤.

        class Program
        {
            static void Main(string[] args)
            {
                List<Student> students = new List<Student>
                {
                    new Student{ Name = "MR.A", Age = 32},
                    new Student{ Name = "MR.B", Age = 34},
                    new Student{ Name = "MR.A", Age = 32}  
                };
                Console.WriteLine("distinctStudents has Count = {0}", students.Distinct().Count());//distinctStudents has Count = 3
                Console.ReadLine();
            }
        }
    

    我们需要达到的是忽略相同数据的对象,但是并没有达到我们如期的效果.因为是distinct默认比较的是对象的引用...所以这样达不到我们预期效果.那我们修改一下来实现我们预期效果.

    在默认情况下Equals具有以下行为:

    • 如果实例是引用类型,则只有引用相同时, Equals才会返回true。
    • 如果实例是值类型,则仅当类型和值相同时, Equals才会返回true。

    Distinct(IEnumerable, IEqualityComparer)

    通过使用指定的 IEqualityComparer 对值进行比较,返回序列中的非重复元素.

    类型参数

    • TSource source 的元素类型。

    参数

    • source IEnumerable 要从中移除重复元素的序列。
    • comparer IEqualityComparer 用于比较值的 IEqualityComparer

    返回

    • IEnumerable
      一个包含源序列中的非重复元素的 IEnumerable

    我们来看如下代码片段

        public class StudentComparator : EqualityComparer<Student>
        {
            public override bool Equals(Student x,Student y)
            {
                return x.Name == y.Name && x.Age == y.Age;
            }
    
            public override int GetHashCode(Student obj)
            {
                return obj.Name.GetHashCode() * obj.Age;
            }
        }
    

    上述代码片段如果两个Equals返回的true并且GetHashCode返回相同的哈希码,则认为两个对象相等.

    重写Equals和GetHashCode

    var stu1 = new Student { Name = "MR.A", Age = 32 };
    var stu2 = new Student { Name = "MR.A", Age = 32 };
       
    bool result = stu1.Equals(stu2); //false because it's reference Equals
    

    上述代码片段执行后结果非预期效果.我们将进一步的去实现代码,以达到预期效果....

        public class Student
        {
            public string Name { get; set; }
    
            public int Age { get; set; }
    
            public override bool Equals(object obj)
            {
                var stu = obj as Student;
                if (stu == null) return false;
                return Name == stu.Name && Age == stu.Age; 
            }
            public override int GetHashCode()
            {
                return Name.GetHashCode() * Age;
            }
        }
        
      var stu1 = new Student { Name = "MR.A", Age = 32 };
      var stu2 = new Student { Name = "MR.A", Age = 32 };
    
      bool result = stu1.Equals(stu2); //result is true
    

    我们再使用LINQ Distinct方法进行过滤和查询,同时将会检查Equals和GetHashCode

        List<Student> students = new List<Student>
        {
            new Student{ Name = "MR.A", Age = 32},
            new Student{ Name = "MR.B", Age = 34},
            new Student{ Name = "MR.A", Age = 32}
        };
        Console.WriteLine("distinctStudents has Count = {0}", students.Distinct().Count()); //distinctStudents has Count = 2
    
  • 相关阅读:
    19年春第六周学习
    Java编程思想
    个人作业4-结对开发地铁
    Hadoop学习笔记—1.基本介绍与环境配置
    ZooKeeper学习第二期--ZooKeeper安装配置
    ZooKeeper学习第一期---Zookeeper简单介绍
    loadrunner--参数化—使用数据文件参数化
    loadrunner--analysis--图表筛选、合并、显示
    loadrunner--并发测试
    session和cookie
  • 原文地址:https://www.cnblogs.com/colorchild/p/12738012.html
Copyright © 2011-2022 走看看