【发布时间】:2011-03-15 17:24:45
【问题描述】:
如果我在 Delphi 中使用 TDictionary 实现关系 Car Owner,我应该如何实现 IEqualityComparer 的 Equals 和 GetHashCode 函数? (GetHashCode 返回一个 Integer,用于 TDictionary 中的散列。)
对于 TVehicle 类,假设它有一个 VIN(车辆识别号)。
我应该如何实现 VIN 的哈希码?
更新:在这个例子中,对象标识不是指“两个对象指针的内存位置的标识”,而是“同一对象的两个实例的标识,基于唯一且不变的(“不可变") 其属性的组合'。
因此,我不需要通过地图中的内存地址搜索车辆,而是需要具有我正在寻找的 id 的车辆。
考虑一个包含车主数据的数据库,在应用程序启动时加载到字典中。现在,如果用户在申请表中输入 VIN,应用程序如何在字典中找到车辆?如果代码使用VehicleFactory.CreateVehicleFromDatabase(Edit1.Text); 创建一个新实例并在字典中搜索此对象,则 Equals 的默认实现不会在映射中找到任何条目,因为它会查找内存地址。为了找到车辆,Equals 需要比较 VIN。
所以我必须创建一个自定义的 IEqualityComparer。实现 Equals 是微不足道的。但是 GetHashCode 呢?对于字符串属性,我不能简单地使用字符串的地址(请参阅Are Delphi strings immutable? 中的 Berry Kelly:“如果您从两个单独的代码部分创建相同的字符串,它们将不会共享相同的后备存储”),所以字符串属性的 GetHashCode 函数需要自定义实现。
我还发现我发现了问题How do I hash a string with Delphi? - 有一个示例包含HashValue('Hello World')
【问题讨论】:
-
字符串的默认比较器不比较地址。
-
拼图中缺少的部分或多或少是字符串的 GetHashCode。在 Delphi 2009 及更高版本中,所有对象都有一个 GetHashCode 方法。字符串不是对象,所以我希望在较新版本的 Delphi 中有一个系统函数。
-
字符串确实有哈希码,它不是基于字符串的地址,而是基于它的内容。你是从哪里知道在 Delphi 中不能对字符串进行哈希处理的?
-
默认字符串哈希如下所示:
BobJenkinsHash(Value[1], Length(Value) * SizeOf(Value[1]), 0)其中Value是string。它正在比较数据。 -
@David 如果这是一个答案,我会接受它wink
标签: delphi generics hashmap tdictionary