我发现自己想要覆盖对象的哈希码和==,我想知道是否有关于如何实现依赖于多个属性的哈希码的最佳实践,并且似乎有一些特定于Dart的注意事项
最简单的答案是将所有属性的哈希值混合在一起,这可能不是太糟糕。在https://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html
的Dart Up和Running中也有一个例子 // 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位。
对于我的应用程序,预期的集合大小非常小,几乎任何事情都可以,但我很惊讶没有看到一般情况的标准配方。有没有人对此有任何经验或丰富经验?
答案 0 :(得分:24)
quiver package提供帮助函数hash2
,hash3
等,这简化了实现hashCode
的任务,并确保它在Dart VM下正常工作编译为JavaScript时和。
import 'package:quiver/core.dart';
class Person {
String name;
int age;
Person(this.name, this.age);
bool operator ==(o) => o is Person && name == o.name && age == o.age;
int get hashCode => hash2(name.hashCode, age.hashCode);
}
另请参阅this post进行稍长时间的讨论。
答案 1 :(得分:10)
为了最小化依赖关系,如果您已经依赖 Flutter,但不依赖于 quiver
之类的东西,dart:ui
库包含实用程序、hashValues
和 {{1}用于创建和组合哈希值。如果组合列表值,必须小心确保相等运算符和哈希码匹配行为。如果哈希码计算它的哈希值很深,则使用深度相等,否则使用浅相等。
hashList
答案 2 :(得分:1)
由于Dart与Java非常相似,所以你肯定可以在适用于Dart的Java hashcode上找到很好的引用。
一个小小的谷歌搜索带我去了Wikipedia page on Java's Object.hashCode()
。有一个简单对象的哈希码的一个非常基本的例子。一种流行的方法是使用素数(不同的)进行乘法,并为对象的每个属性添加一些值。
This question f.e。解释为什么选择数字31进行String.hashCode()
方法的乘法运算。
使用Google可以轻松找到更详细的哈希码实现示例。
答案 3 :(得分:1)
虽然这不是一个很好的答案,但是在https://code.google.com/p/dart/issues/detail?id=11617提供这个问题还有一个公开的错误,并且引用的“Jenkins SMI哈希”似乎是公开可用的最佳选择。
答案 4 :(得分:0)
equatable软件包可以提供帮助
import 'package:equatable/equatable.dart';
class Person extends Equatable {
final String name;
final int age;
Person(this.name, this.age);
@override
List<Object> get props => [name, age];
}
答案 5 :(得分:-1)
我推荐“等效”插件
https://pub.dev/packages/equatable
示例:
原始模式:
class Person {
final String name;
const Person(this.name);
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is Person &&
runtimeType == other.runtimeType &&
name == other.name;
@override
int get hashCode => name.hashCode;
}
具有等于数:
import 'package:equatable/equatable.dart';
class Person extends Equatable {
final String name;
Person(this.name);
@override
List<Object> get props => [name];
}