飞镖,异或两个哈希码总是会返回一个新的唯一哈希码吗?

Dan*_*son 6 hashcode dart

我正在编写一个需要基于其两个字段的唯一哈希码的类,我想知道对 2 个字段哈希码进行异或是否足以为我的对象生成唯一且一致的哈希码?

class _TypeMatch{
  final Type _potentialSubtype;
  final Type _supertype;

  int _cachedHashCode;  

  _TypeMatch(this._potentialSubtype, this._supertype){
    _cachedHashCode = _potentialSubtype.hashCode ^ _supertype.hashCode;
  }

  int get hashCode => _cachedHashCode;

  bool operator ==(other){
    return other is _TypeMatch && _cachedHashCode == other._cachedHashCode;
  }
}
Run Code Online (Sandbox Code Playgroud)

我在这里看到了这个问题它似乎表明对另外两个哈希码进行异或是正确的做法,但它们首先将每个哈希码乘以 2 个大素数,我不确定为什么或是否有必要这样做。我主要关心的是对于两种类型 A 和 B:

new _TypeMatch(A, B) == new _TypeMatch(A, B) // is true for all A and B
Run Code Online (Sandbox Code Playgroud)

并且组合散列的计算尽可能高效,因为创建新的 _TypeMatch 将成为系统的核心部分,因此在整个系统中会明显感觉到任何性能低效。

更新

哈希码用于例如哈希映射或哈希表,以将存储的键/值平均分配到“槽”中。一个槽可以包含许多键/值,但通过使用哈希码,可以轻松快捷地在映射中找到一个槽,并从那里在更小的一组值中查找具体的键/值。无论键使用哪种数据类型,这都可以非常快速地提高在地图中搜索的速度。当哈希码为存储的键/值更改时,无法再通过键检索该值。你可以用1作为每个对象的哈希码,但这会破坏性能。您会通过良好的分布(不同对象的不同哈希码)获得相反的效果(最佳性能),但存在限制。例如,当您使用 32 位整数类型作为哈希码时,可能的哈希码数量是有限的。有关更多详细信息,请参阅http://en.wikipedia.org/wiki/Hash_table。不过,散列还有更多用例。

Gün*_*uer 5

我建议使用hash2quiver 包中的方法

https://github.com/google/quiver-dart/blob/master/lib/src/core/hash.dart#L26

你可以像这样使用它

import 'package:quiver/core.dart' show hash2;

@override
int get hashCode => hash2(val1, val2);
Run Code Online (Sandbox Code Playgroud)

他们使用此代码来组合哈希码

int _combine(int hash, int value) {
  hash = 0x1fffffff & (hash + value);
  hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
  return hash ^ (hash >> 6);
}
Run Code Online (Sandbox Code Playgroud)

更新

(来自我在问题下面的评论)

hashcode应该是唯一的。但它不会改变很重要。相同的对象应该返回相同的哈希码,但这并不意味着不同的对象需要具有不同的哈希码。您不应该使用 hashCode 来检查相等性。

  • 正如 Günter 在对原始问题的评论中所解释的那样,“hashCode”合约不要求对象的哈希码是唯一的,只要求彼此“==”的两个对象必须具有相同的“hashCode”。如果您需要唯一的哈希代码,则不应依赖 Dart 的内置“hashCode”,而应自行创建以确保唯一性。 (2认同)