我必须将对象与同一个类的原始属性进行比较。 意思是,我必须比较那些:
struct Identifier
{
string name;
string email;
}
使用两个字符串名称和电子邮件。 我知道我可以为名称和电子邮件创建一个新的Identifier实例,并将其传递给equals()。我的申请必须非常快速且节省资源。
我知道通过哈希码进行比较并不是一个好方法,因为正如here所解释的那样,存在冲突。但碰撞对我来说没问题,我只需要快速。
所以,
1)通过GetHashCode进行比较(检查两个对象的哈希码是否相同)比Equals()更快?
2)我是否应该为比较创建两个值的标识符的新实例,创建一个直接获取值的新方法? e.g。
struct Identifier {
string name;
string email;
bool Equals(string name, string email) {
// todo comparison via hashcode or equals
}
}
I would use the Equals() and GetHashCode() method generated by resharper.
答案 0 :(得分:6)
如果将哈希代码保存在Identifier
实例上,则比较哈希代码会更快(见下文)。但是,与平等比较并不是一回事。
比较哈希码可以让你检查两个项目是否不彼此相等:当你得到不同的哈希码时,你知道这一点。
但是,当哈希码相等时,您无法对相等性做出明确的陈述:项目可以相等或不相等。这就是为什么基于散列的容器必须始终遵循哈希代码比较,直接或间接,并进行相等性比较。
尝试按照以下方式实施比较:
struct Identifier {
string name;
string email;
int nameHash;
int emailHash;
public Identifier(string name, string email) {
this.name = name;
nameHash = name.GetHashCode();
this.email = email;
emailHash = email.GetHashCode();
}
bool Equals(string name, string email) {
return name.GetHashCode() == nameHash
&& email.GetHashCode() == emailHash
&& name.equals(this.name)
&& email.equals(this.email);
}
}
与预先计算的哈希代码相比,会使实际的相等比较短路,因此当大多数比较最终返回false
时,您可以节省一些CPU周期。
答案 1 :(得分:5)
是通过GetHashCode进行比较(检查两个对象的哈希码 是相同的)比Equals()更快?
你似乎混淆了这两个概念。 GetHashCode
的目的不是寻求两个对象实例之间的相等,它就是这样,每个对象都可以轻松地为任何外部资源提供哈希码值。继续它。
Equals
是确定平等的。应该是两个为equals生成true
的方法,提供相同的哈希码,但不是相反。
The documentation on object.GetHashCode
提供了一个非常好的解释:
两个相等的对象返回相等的哈希码。然而, 相反的情况并非如此:相等的哈希码并不意味着对象 相等,因为不同(不相等)的对象可以具有相同的哈希值 码。此外,.NET Framework不保证默认值 执行GetHashCode方法,以及此方法的值 .NET Framework版本和平台之间的返回可能不同,例如 作为32位和64位平台。由于这些原因,请不要使用 此方法的默认实现作为唯一对象标识符 用于散列目的。由此产生两种结果:
- 您不应该假设相等的哈希码意味着对象相等。
- 您永远不应该在应用程序域之外持久存储或使用哈希代码 它是创建它的,因为同一个对象可以散列 应用程序域,进程和平台。
如果您想检查两个实例之间的相等性,我绝对建议您实施IEquatable<T>
并覆盖object.GetHashCode
。
作为旁注 - 我发现您正在使用struct
。你应该注意到struct
在C#中的语义与在C ++或C中的语义不同,我希望你能够意识到它们。