C#에서 GetHashCode 및 Equals
6818 단어 HashCode
만약에 우리가 Person 클래스를 가지고 있다면,Hash 기반 Collection(예를 들어HashTable과Dictionary)에 줄 키에게Hash 값을 정의하면 두 개의Person 실례 id가 다르지만 이름은 같다
코드는 다음과 같습니다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TestGetHashCode
{
class Program
{
static void Main(string[] args)
{
IDictionary<Person, Object> dic = new Dictionary<Person,Object>();
Person p1 = new Person();
p1.Id = 1;
p1.Name = "name1";
p1.Age = 20;
dic.Add(p1, "111");
Person p2 = new Person();
p2.Id = 2;
p2.Name = "name2";
p2.Age = 20;
dic.Add(p2, "222");
if (dic.ContainsKey(p1))
{
Console.WriteLine("Contains");
}
else
{
Console.WriteLine("Not Contains");
}
// IList<Person> list = new List<Person>();
}
}
class Person
{
private object parent;
public object Parent
{
get { return parent; }
set { parent = value; }
}
private int id;
public int Id
{
get { return id; }
set { id = value; }
}
private string name;
private int age;
public int Age
{
get { return age; }
set { age = value; }
}
public string Name
{
get { return name; }
set { name = value; }
}
public override int GetHashCode()
{
Console.WriteLine("In GetHashCode");
// Random num = new Random();
// int a = num.Next(1,100);
int hashCode = (this.Id == 0 || this.Id == null) ? 0 : this.Id.GetHashCode();
if (this.parent != null)
{
hashCode = 31 * hashCode + this.parent.GetHashCode();
}
return hashCode;
}
public override bool Equals(object obj)
{
Console.WriteLine("Equal ");
if (obj == null || GetType() != obj.GetType())
{
return false;
}
return this.Id == (obj as Person).Id;
}
}
}
dic를 실행하고 있습니다.Add(p1, "111"); GetHashCode만 호출됩니다.
dic를 실행하고 있습니다.Add(p2, "222"); GetHashCode만 호출하고 Equals 방법은 호출하지 않습니다.
Personp2의 Id를 P1의 Id와 동일하게 변경하면 ArgumentException {"An item with the same key has already been added."}
이렇게 하면 같은 Id가 있는 Person 실례가 집합에 추가되는 것을 방지할 수 있다
그래서 이렇게 하면 두 실체가 같다는 것을 증명할 수 있다. 그들의 HashCode는 반드시 같지만 HashCode는 반드시 같지 않다. 두 실체는 반드시 같지 않다.
if(dic.ContainsKey(p1)를 실행할 때, 먼저 p1의 GetHashCode 방법을 호출하고 Equals 방법을 조정합니다.
만약 우리가 프로그램을 수정하면, Id는 같을 수 있지만, 이름이 다른 사람도 집합dic에 가입할 수 있다
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TestGetHashCode
{
class Program
{
static void Main(string[] args)
{
IDictionary<Person, Object> dic = new Dictionary<Person,Object>();
Person p1 = new Person();
p1.Id = 1;
p1.Name = "name1";
p1.Age = 20;
dic.Add(p1, "111");
Person p2 = new Person();
p2.Id = 1;
p2.Name = "name2";
p2.Age = 20;
dic.Add(p2, "222");
if (dic.ContainsKey(p1))
{
Console.WriteLine("Contains");
}
else
{
Console.WriteLine("Not Contains");
}
}
}
class Person
{
private object parent;
public object Parent
{
get { return parent; }
set { parent = value; }
}
private int id;
public int Id
{
get { return id; }
set { id = value; }
}
private string name;
private int age;
public int Age
{
get { return age; }
set { age = value; }
}
public string Name
{
get { return name; }
set { name = value; }
}
public override int GetHashCode()
{
Console.WriteLine("In GetHashCode");
// Random num = new Random();
// int a = num.Next(1,100);
int hashCode = (this.Id == 0 || this.Id == null) ? 0 : this.Id.GetHashCode();
if (this.parent != null)
{
hashCode = 31 * hashCode + this.parent.GetHashCode();
}
return hashCode;
}
public override bool Equals(object obj)
{
Console.WriteLine("Equal ");
if (obj == null || GetType() != obj.GetType())
{
return false;
}
return this.Id == (obj as Person).Id && this.Name == (obj as Person).Name;
}
}
}
dic를 실행하고 있습니다.Add(p2, "222"); GetHashCode 외에도 Equals 방법을 사용할 수 있습니다
if(dic.ContainsKey(p1)를 실행할 때, 먼저 p1의 GetHashCode 방법을 호출하고 Equals 방법을 조정합니다.이번에는 두 번의 Equals 방법을 사용합니다. 왜냐하면 이때 p1과 p2가 dic 집합 안에 있는HashCode는 모두 같기 때문입니다.처음으로 전송된obj와p2를 비교한 다음에 p1과obj를 비교하여 최종적으로Contains를 출력합니다
Java에서 이 덩어리의 원리는 C#와 같다
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
EffectiveJava - 모든 객체에 공통적인 메서드equals 방법을 덮어쓰지 않을 때, 클래스의 모든 실례는 그 자체와 같다 예를 들어 Random은 equals 방법을 실현하여 두 Random이 발생하는 무작위 수가 같은지 판단하는데 사용하지만 디자이너는 클라이...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.