dart,xoring两个哈希码总是会返回一个新的唯一哈希码?

时间:2014-10-30 08:53:36

标签: dart hashcode

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

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;
  }
}

我已经看到了这个问题here,这似乎表明XORing其他两个哈希码是正确的做法,但他们首先将每个哈希码多次用2个大质数,我不知道为什么或者这是必要的。我主要关注两种类型A和B:

new _TypeMatch(A, B) == new _TypeMatch(A, B) // is true for all A and B

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

更新

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

1 个答案:

答案 0 :(得分:3)

我建议使用quiver package

中的hash2方法

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);

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

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

<强>更新

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

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