HashCode对于我这种菜鸟来说,听过,见过,但是具体是干什么的,我不知道。问度娘,看着大家五花八门的解释,我蛋疼了,于是今天有空闲就研究下这玩意,看看这玩意到低是干什么的。 在Msdn上对于Hashcode是这样:用作特定类型的哈希函数。这句话不得不说很抽象,不过还好有备注:GetHashCode方法的默认实现不保证针对不同的对象返回唯一值。 而且,.NET Framework 不保证 GetHashCode 方法的默认实现以及它所返回的值在不同版本的 .NET Framework 中是相同的。 因此,在进行哈希运算时,该方法的默认实现不得用作唯一对象标识符。
好吧,不扯这些理论东西了,大家没事可以去MSDN看看这个东西,我们用代码验证下这玩意。
1,值类型的HashCode分析:
class Program
{
static void Main(string[] args)
{
int hashCodeA = 0;
int hashCodeB = 0;
Console.WriteLine("hashCodeA的值和hashCodeB的值相等的情况Hashcode值分别是");
Console.WriteLine(hashCodeA.GetHashCode()+"::::"+hashCodeB.GetHashCode());
hashCodeB = 1;
Console.WriteLine("hashCodeA的值和hashCodeB的值不相等的情况Hashcode值分别是");
Console.WriteLine(hashCodeA.GetHashCode() + "::::" + hashCodeB.GetHashCode());
}
}
运行的结果:
来,小伙伴们,我们来看第二值类型:关于Struct的
public struct StructHashCode//定义一个结构体{
public int a;
public int b;
}
class Program
{
static void Main(string[] args)
{
StructHashCode sCode1 = new StructHashCode();
sCode1.a = 1;
sCode1.b = 1;
StructHashCode sCode2 = new StructHashCode();
sCode2.a = 1;
sCode2.b = 1;
if (sCode1.GetHashCode() == sCode2.GetHashCode())
Console.WriteLine("我们是相等的哦,亲");
else
Console.WriteLine("我们是不想等的哦,亲");
Console.WriteLine("********华丽分割线***********");
sCode2.a = 1;
sCode2.b = 2;
if (sCode1.GetHashCode() == sCode2.GetHashCode())
Console.WriteLine("我们是相等的哦,亲");
else
Console.WriteLine("我们是不想等的哦,亲");
Console.WriteLine("********华丽分割线***********");
sCode2.a = 2;
sCode2.b = 2;
if (sCode1.GetHashCode() == sCode2.GetHashCode())
Console.WriteLine("我们是相等的哦,亲");
else
Console.WriteLine("我们是不想等的哦,亲");
}
}
运行结果:(看到这个结果我想骂娘了)
这两个关于值类性的例子大家是不是有种困惑的感觉,很抱歉的是,我也不能给大家解释这是为什么,但是我们最起码验证了:HashCode看来是个栈地址是没什么关系的。希望有大拿帮我解惑。
2,引用类型的HashCode分析:
class Program
{
static void Main(string[] args)
{
ClassHashCode classCode1 = new ClassHashCode();
ClassHashCode classCode2 = new ClassHashCode();
ClassHashCode classCode3 = classCode1;
Console.WriteLine("classCode1和classCode2的HashCode进行比较");
if (classCode1.GetHashCode() == classCode2.GetHashCode())
Console.WriteLine("我们是相等的哦,亲");
else
Console.WriteLine("我们是不想等的哦,亲");
Console.WriteLine("******华丽的分割线******");
Console.WriteLine("classCode1和classCode3的HashCode进行比较");
if (classCode1.GetHashCode() == classCode3.GetHashCode())
Console.WriteLine("我们是相等的哦,亲");
else
Console.WriteLine("我们是不想等的哦,亲");
}
}
public class ClassHashCode
{
}
运行的结果:
那么关于classCode1 和classCode2和classCode3之间的关于堆和栈的那点区别,在这我就本给大家叙述了,不懂可以问问度娘。
到这里我想就可以做个总结了:无论是值类型还是引用类型,最终来说都是Object对象,那么对象与对象之间如果相等,HashCode一定是一样的,如果不想等,HashCode也不一定不一样(因为有值类型这样的怪东西)。事情发展到这里大家就多少明白点了吧,HashCode有太多不确定的。以上是个人观点,希望大拿指正。。
上文提到classCode1和classCode2是不想等的,但是如果我们忽略HashCode不相等(堆和栈的引用地址不等,这时候看来,HashCode好像也和地址有关联),那么我就可以认为他们是相等的了,大家是不是就想到对象的重复的筛选。
IEqualityComparer<T>就出现啦,他的具体含义大家可以看看MSDN哦 ,具体代码实现:
class Program
{
static void Main(string[] args)
{
UserComparer userComparer = new UserComparer();
People people1 = new People(1, "huhu");
People people2 = new People(1, "huhu");
People people3 = new People(2, "lala");
People people4 = new People(2, "lala");
People people5 = new People(3, "gaga");
People people6 = new People(3, "gaga");
People people7 = new People(4, "momo");
List<People> peopleList = new List<People>();
peopleList.Add(people1);
peopleList.Add(people2);
peopleList.Add(people3);
peopleList.Add(people4);
peopleList.Add(people5);
peopleList.Add(people6);
peopleList.Add(people7);
var newPeopleList = peopleList.Distinct(userComparer);
foreach (var item in newPeopleList)
{
Console.WriteLine(item.ID + "::::" + item.Name);
}
}
}
/// <summary>
/// 定义people的类
/// </summary>
public class People
{
public int ID { get; set; }
public string Name { get; set; }
public People(int id, string name)
{
ID = id;
Name = name;
}
}
/// <summary>
/// 实现IEqualityComparer的接口对于类型 pepple,您可以创建自己的相等定义
/// </summary>
public class UserComparer : IEqualityComparer<People>
{
/// <summary>
/// 自己定义people对象的相等的规则
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
public bool Equals(People x, People y)
{
if (x.ID == y.ID && x.Name == y.Name)
return true;
else
return false;
}
/// <summary>
/// 自己定义peopel的Hashcode的返回规则,我这里关于people这个对象的hashcode都是0(为了省事)
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public int GetHashCode(People obj)
{
return 0;
}
}
运行的结果的:
通过以上验证,我个人认为,对象之间的相等和HashCode有这藕断丝连的感觉,但是对这个HashCode还是感觉有种意犹未尽,想伸进去,但是又找不到门路的感觉,喜欢能抛砖引玉,引来大拿为我解惑。。。