加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

delphi – 为TEqualityComparer.Construct编写hasher函数的规范

发布时间:2020-12-15 10:06:29 所属栏目:大数据 来源:网络整理
导读:请考虑以下记录: TMyRecord = record b: Boolean; // 3 bytes of padding in here with default record alignment settings i: Integer;end; 我希望实现IEqualityComparer TMyRecord.为此,我想调用TEqualityComparer TMyRecord .Construct.这需要提供TEQUal
请考虑以下记录:
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.

A good hash function tends to produce unequal hash codes for unequal
objects. This is exactly what is meant by the third provision of the
hashCode contract. Ideally,a hash function should distribute any
reasonable collection of unequal instances uniformly across all
possible hash values. Achieving this ideal can be extremely difficult.
Luckily it is not too difficult to achieve a fair approximation. Here
is a simple recipe:

  1. Store some constant nonzero value,say 17,in an int variable called result.
  2. For each significant field f in your object (each field taken into account by the equals method,that is),do the following:

    a. Compute an int hash code c for the field: ….. details omitted ….

    b. Combine the hash code c computed in step a into
    result as follows: result = 37*result + c;

  3. Return result.

  4. When you are done writing the hashCode method,ask yourself whether equal instances have equal hash codes. If not,figure out why
    and fix the problem.

这可以转换成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,1),Value.i]);
end;

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读