dart,xoring两个哈希码总是会返回一个新的唯一哈希码?(dart, is xoring two hashcodes always going to return a new unique ha

编程入门 行业动态 更新时间:2024-10-21 07:32:45
dart,xoring两个哈希码总是会返回一个新的唯一哈希码?(dart, is xoring two hashcodes always going to return a new unique 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;
  }
}
 

我在这里看到了这个问题似乎表明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 。 但是哈希还有更多的用例。

I am writing a class that needs to have a unique hashcode based on two of its fields and I wanted to know whether XORing the 2 fields hashcodes is enough to generate a unique and consistent hashcode for my object?

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

I have seen this question here which seems to suggest that XORing two other hashcodes is the correct thing to do but they multiiply each hashcode by 2 large primes first, and I wasnt sure why or if this was necessary. I'm primarily concerned that for two Types A and B:

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

and that the calculation of the combined hash is as efficient as possible as creating a new _TypeMatch is going to be a core part of the system and so any performance inefficiencies will be felt drastically throughout the system.

Update

Hashcodes are used for example in a hashmap or hashtable to distribute the stored key/values equally into 'slots'. One slot can contain many key/values but by using the hashcode it is easy and quick to find a slot in the map and from there to look for a concrete key/value in a much smaller set of values. This improves the speed when searching in a map very fast no matter what kind of data type is used for the key. When the hashcode would change for a stored key/value the value can't be retrieved anymore by key. You could just use 1 as hashcode for every object but this would ruin the performance. You get the opposite effect (optimal performance) with a good distribution (different hashcodes for different objects) but there is a limit. When you use for example a 32bit integer type for the hashcode the number of possible hashcodes is limited. See http://en.wikipedia.org/wiki/Hash_table for more details. There are many more use cases for hashes though.

最满意答案

我建议使用quiver包中的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);
}

I suggest using the hash2 method from quiver package

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

You can use it like

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

@override
int get hashCode => hash2(val1, val2);
 

They use this code to combine hash codes

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

update

(from my comment below the question)

The hashcode isn't supposed to be unique. That it doesn't change is important though. Equal objects should return the same hashcode but that doesn't mean that different objects need to have different hashcodes. You shouldn't use the hashCode for checking equality.

更多推荐

本文发布于:2023-08-07 04:32:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1460773.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:两个   哈希码   dart   xoring   唯一哈希码

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!