我发现自己想为一个对象覆盖hashcode和==,我想知道是否有最佳实践来实现依赖于多个属性的hashcode,似乎有一些Dart特定的考虑因素。
最简单的答案是对所有属性的哈希值进行异或,这可能不会太糟糕。
// Override hashCode using strategy from Effective Java, Chapter 11.
int get hashCode {
int result = 17;
result = 37 * result + firstName.hashCode;
result = 37 * result + lastName.hashCode;
return result;
}
字符串
但这看起来像是它期望截断整数语义,而在Dart中,JS整数的范围溢出似乎不利于哈希。
我们也可以这样做,在每次操作后截断为32位。
对于我的应用程序来说,集合的预期大小非常小,几乎任何东西都可以,但我很惊讶没有看到一般情况下的标准配方。有人对此有任何经验或经验丰富吗?
6条答案
按热度按时间du7egjpx1#
quiver package提供了帮助函数
hash2
、hash3
等,这些帮助函数简化了hashCode
的实现任务,并在一定程度上保证了hashCode
在Dart VM * 和 * 下编译为JavaScript时能够正常工作。字符串
另请参阅this post以获得稍微详细的讨论。
jv2fixgn2#
从2.14版开始,Dart语言增加了对
Object.hash()
的支持,沿着还有Object.hashAll()
和Object.hashAllUnordered()
hash()
文档:为多个对象创建组合哈希代码。
范例:
字符串
关于实施的文件说明:
此函数生成的哈希值不能保证在同一程序的不同运行中或在同一程序的不同隔离中运行的代码之间保持稳定。所使用的确切算法可能在不同平台之间或平台库的不同版本之间有所不同,并且可能取决于每次程序执行时更改的值。
2w3rbyxf3#
为了最小化依赖关系,如果你已经依赖于flutter,但不依赖于像
quiver
这样的东西,dart:ui
库包含用于创建和组合哈希值的工具,hashValues
和hashList
。如果组合列表值,必须小心确保相等运算符和hashcode匹配行为。如果哈希代码深入计算它的哈希,然后使用深度相等,否则使用浅相等。字符串
Flutter API docs for hashValues
Flutter API docs for hashList的
o2rvlv0m4#
equatable软件包可以帮助
字符串
现在Person将使用来自Equatable的
==
和hashCode
,Equatable接受您给予的props
列表atmip9wb5#
我recomend“equatable”插件
https://pub.dev/packages/equatable
范例:
原始模式:
字符串
equatable:
型
ctrmrzij6#
由于Dart与Java非常相似,您肯定可以找到适用于Dart的Java hashCodes的好参考资料。
我在谷歌上搜索了一下Wikipedia page on Java's
Object.hashCode()
。它有一个简单对象的散列代码的非常基本的例子。一个流行的方法是用一个素数(不同的素数)执行乘法,并为对象的每个属性添加一些值。This question f.e.解释了为什么选择数字31作为
String.hashCode()
方法的乘法。更详细的hashcode实现的例子可以很容易地使用Google找到。