GetHashCode 好的做法?
GetHashCode good practice?
对于 Delphi 项目(使用 RAD Studio XE7 构建),我想创建一个画笔字典。每个字典项都包含一个 TMyBrush 对象作为键,它描述了要检索的画笔,一个 GDI+ 画笔作为值。
TMyBrush class 包含 3 个字段
- 一个枚举类型,用于确定画笔的种类(纯色、渐变...)
- 描述画笔内容(颜色、环绕模式...)的 TBrushInfo class
- 表示钳位场的 TRect
在我的字典中,我想根据他的特征而不是他的实例来检索画笔。例如,我想通过创建本地 TMyBrush 实例、将其配置为黑色实体并使用 TryGetValue() 函数获取匹配的 GDI+ 值,从我的字典中获取黑色实体画笔。为此,我创建了一个 TMyBrushComparer。
编写 Equals() 函数对我来说不是问题。但是我不知道编写 GetHashCode() 函数的最佳做法是什么。我倾向于编写这样的函数:
function TMyBrushComparer.GetHashCode(const pValue: TMyBrush): Integer;
begin
Result := BobJenkinsHash(pValue, SizeOf(TMyBrush), 0);
end;
但是我觉得这不是一个很好的做法,它是正确的吗?那么,为我的 TMyBrushComparer 编写好的 GetHashCode() 函数的最佳做法是什么?
此致
问题中的代码对对象的地址而不是其值进行哈希处理,因此与您对相等性的定义不一致。
您对相等的定义是三个字段相等。您的散列函数应符合该定义。散列三个字段中的每一个,并组合这些值,例如使用此处概述的方法:
您的两个字段是值类型。它们很容易散列以匹配价值身份。画笔信息字段似乎是参考类型。因此,您需要再次决定所需的身份形式(引用身份、值身份或其他可能),然后实施匹配相等性测试和哈希。
对于 Delphi 项目(使用 RAD Studio XE7 构建),我想创建一个画笔字典。每个字典项都包含一个 TMyBrush 对象作为键,它描述了要检索的画笔,一个 GDI+ 画笔作为值。
TMyBrush class 包含 3 个字段
- 一个枚举类型,用于确定画笔的种类(纯色、渐变...)
- 描述画笔内容(颜色、环绕模式...)的 TBrushInfo class
- 表示钳位场的 TRect
在我的字典中,我想根据他的特征而不是他的实例来检索画笔。例如,我想通过创建本地 TMyBrush 实例、将其配置为黑色实体并使用 TryGetValue() 函数获取匹配的 GDI+ 值,从我的字典中获取黑色实体画笔。为此,我创建了一个 TMyBrushComparer。
编写 Equals() 函数对我来说不是问题。但是我不知道编写 GetHashCode() 函数的最佳做法是什么。我倾向于编写这样的函数:
function TMyBrushComparer.GetHashCode(const pValue: TMyBrush): Integer;
begin
Result := BobJenkinsHash(pValue, SizeOf(TMyBrush), 0);
end;
但是我觉得这不是一个很好的做法,它是正确的吗?那么,为我的 TMyBrushComparer 编写好的 GetHashCode() 函数的最佳做法是什么?
此致
问题中的代码对对象的地址而不是其值进行哈希处理,因此与您对相等性的定义不一致。
您对相等的定义是三个字段相等。您的散列函数应符合该定义。散列三个字段中的每一个,并组合这些值,例如使用此处概述的方法:
您的两个字段是值类型。它们很容易散列以匹配价值身份。画笔信息字段似乎是参考类型。因此,您需要再次决定所需的身份形式(引用身份、值身份或其他可能),然后实施匹配相等性测试和哈希。