java gethashcode equals_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 students = new List

{

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

{

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 students = new List

{

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

作者:@冯辉

出处:https://www.cnblogs.com/yyfh/p/12245916.html?utm_source=tuicool&utm_medium=referral

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值