我正在尝试理解接口IEqualityComparer的GetHashCode方法的作用。
以下示例取自MSDN:
using System;
using System.Collections.Generic;
class Example {
static void Main() {
try {
BoxEqualityComparer boxEqC = new BoxEqualityComparer();
Dictionary<Box, String> boxes = new Dictionary<Box,
string>(boxEqC);
Box redBox = new Box(4, 3, 4);
Box blueBox = new Box(4, 3, 4);
boxes.Add(redBox, "red");
boxes.Add(blueBox, "blue");
Console.WriteLine(redBox.GetHashCode());
Console.WriteLine(blueBox.GetHashCode());
}
catch (ArgumentException argEx) {
Console.WriteLine(argEx.Message);
}
}
}
public class Box {
public Box(int h, int l, int w) {
this.Height = h;
this.Length = l;
this.Width = w;
}
public int Height { get; set; }
public int Length { get; set; }
public int Width { get; set; }
}
class BoxEqualityComparer : IEqualityComparer<Box> {
public bool Equals(Box b1, Box b2) {
if (b1.Height == b2.Height & b1.Length == b2.Length
& b1.Width == b2.Width) {
return true;
}
else {
return false;
}
}
public int GetHashCode(Box bx) {
int hCode = bx.Height ^ bx.Length ^ bx.Width;
return hCode.GetHashCode();
}
}
Equals方法实现不应该足以比较两个Box对象吗?这就是我们告诉框架用于比较对象的规则的地方。为什么需要GetHashCode?
谢谢。
卢西恩
发布于 2015-03-19 01:49:00
虽然Dictionary<TKey,TValue>
有可能让它的GetValue
和类似的方法在每个存储的键上调用Equals
,以查看它是否与正在查找的键匹配,但这将非常慢。相反,与许多基于散列的集合一样,它依赖于GetHashCode
来快速排除大多数不匹配的值。如果在被查找的项上调用GetHashCode
得到42,并且集合有53,917项,但是在53,914项上调用GetHashCode
产生的值不是42,那么只有3项必须与被查找的项进行比较。其他53,914个可以安全地忽略。
在IEqualityComparer<T>
中包含GetHashCode
的原因是考虑到字典的使用者可能希望将通常不会将彼此视为相等的对象视为相等的对象。最常见的例子是调用者希望使用字符串作为键,但使用不区分大小写的比较。为了高效地工作,字典将需要某种形式的散列函数,该散列函数将为"FOX“和"Fox”产生相同的值,但希望为"box“或"zebra”产生其他值。由于内置到String
中的GetHashCode
方法不能以这种方式工作,因此字典将需要从其他地方获取这样的方法,而IEqualityComparer<T>
是最符合逻辑的地方,因为对这样的散列代码的需要将与认为"Fox“和"FOX”彼此相同而不是"box“或"zebra”的Equals
方法紧密相关。
https://stackoverflow.com/questions/4095395
复制相似问题