考虑以下记录:
TMyRecord = record
b: Boolean;
// 3 bytes of padding in here with default record alignment settings
i: Integer;
end;
我希望实现
IEqualityComparer<TMyRecord>
。为此,我想调用TEqualityComparer<TMyRecord>.Construct
。这需要提供一个TEqualityComparison<TMyRecord>
,它对我没有任何问题。但是,
Construct
也需要THasher<TMyRecord>
,我想知道实现该规范的方法。该函数必须具有以下形式:function MyRecordHasher(const Value: TMyRecord): Integer;
begin
Result := ???
end;
我希望我需要在记录值的两个字段上调用
BobJenkinsHash
,然后将它们结合起来。这是正确的方法,我应该如何将它们结合起来?我不使用
TEqualityComparison<TMyRecord>.Default
的原因是它使用了CompareMem
,因此由于记录的填充而将是不正确的。 最佳答案
有关覆盖hashCode的Effective Java (by Joshua Bloch)部分可能会很有用。它显示了如何组合对象(或记录)的各个部分以有效地构造hashCode。
可以将其转换为Delphi代码,如下所示:
{$IFOPT Q+}
{$DEFINE OverflowChecksEnabled}
{$Q-}
{$ENDIF}
function CombinedHash(const Values: array of Integer): Integer;
var
Value: Integer;
begin
Result := 17;
for Value in Values do begin
Result := Result*37 + Value;
end;
end;
{$IFDEF OverflowChecksEnabled}
{$Q+}
{$ENDIF}
然后,这可以实现
MyRecordHasher
:function MyRecordHasher(const Value: TMyRecord): Integer;
begin
Result := CombinedHash([IfThen(Value.b, 0, 1), Value.i]);
end;
关于delphi - 为TEqualityComparer.Construct编写哈希函数的规范方法是什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11294686/