什么';在Dart中重写哈希代码的好方法是什么?
我发现自己想要覆盖一个对象的hashcode和==,我想知道,对于如何实现依赖于多个属性的hashcode,是否有最佳实践,而且似乎有一些特定于Dart的注意事项 最简单的答案是将所有属性的散列异或在一起,这可能不是太糟糕。还有一个例子,在飞镖和运行在什么';在Dart中重写哈希代码的好方法是什么?,dart,hashcode,Dart,Hashcode,我发现自己想要覆盖一个对象的hashcode和==,我想知道,对于如何实现依赖于多个属性的hashcode,是否有最佳实践,而且似乎有一些特定于Dart的注意事项 最简单的答案是将所有属性的散列异或在一起,这可能不是太糟糕。还有一个例子,在飞镖和运行在 //使用有效Java的策略覆盖哈希代码,第11章。 int获取哈希代码{ int结果=17; 结果=37*result+firstName.hashCode; 结果=37*result+lastName.hashCode; 返回结果; } 但这
//使用有效Java的策略覆盖哈希代码,第11章。
int获取哈希代码{
int结果=17;
结果=37*result+firstName.hashCode;
结果=37*result+lastName.hashCode;
返回结果;
}
但这似乎需要截断整数语义,而在Dart中溢出JS整数的范围似乎不利于散列
我们也可以这样做,每次操作后只需截断到32位
对于我的应用程序,集合的预期大小非常小,几乎任何东西都可以,但是我很惊讶没有看到一个适用于一般情况的标准配方。有人对此有经验吗?由于Dart与Java非常相似,您肯定可以找到适用于Dart的Java哈希代码的好参考 我在谷歌上搜索了一下,就到了图书馆。有一个简单对象的hashcode的基本示例。一种流行的方法是使用质数(不同的质数)进行乘法,并为对象的每个属性添加一些值 f.e.解释了为什么选择数字31作为
String.hashCode()
方法的乘法
使用Google可以很容易地找到hashcode实现的更详细示例。提供了帮助函数hash2
、hash3
,这些函数简化了实现hashcode
的任务,并在一定程度上保证了它在Dart VM下以及编译为JavaScript时能够正常工作
导入“包:quiver/core.dart”;
班主任{
字符串名;
智力年龄;
人(这个名字,这个年龄);
布尔运算符==(o)=>o是Person&&name==o.name&&age==o.age;
int get hashCode=>hash2(name.hashCode,age.hashCode);
}
另请参阅,以获得更为冗长的讨论。该软件包可以提供帮助
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];
}
import'包:equalable/equalable.dart';
类Person扩展了equalable{
最后的字符串名;
最终积分;
人(这个名字,这个年龄);
@凌驾
列表获取道具=>[姓名、年龄];
}
现在,此人将使用Equatable中的==
和hashCode
,这将获得您提供的道具列表我推荐“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];
}
import'包:equalable/equalable.dart';
类Person扩展了equalable{
最后的字符串名;
人员(姓名);
@凌驾
列表获取道具=>[name];
}
为了最小化依赖性,如果您已经依赖于flift,但不依赖于类似于quiver
的东西,dart:ui
库包含用于创建和组合散列值的实用程序、hashValues
和hashList
。如果组合列表值,必须小心确保相等运算符和哈希代码匹配行为。如果哈希代码计算其哈希深度,则使用深度相等,否则使用浅相等
class Example {
final String value1;
final Object value2;
final List<Object> deep;
final List<Object> shallow;
Example({this.value1, this.value2, this.deep, this.shallow});
@override
operator ==(o) =>
o is Example &&
o.value1 == value1 &&
o.value2 == value2 &&
listEquals(o.deep, deep) &&
o.shallow == shallow;
@override
int get hashCode => hashValues(value1, value2, hashList(deep), shallow);
}
类示例{
最终字符串值1;
最终目标值2;
最后的名单很深;
最终名单;
示例({this.value1,this.value2,this.deep,this.shallow});
@凌驾
运算符==(o)=>
o是一个例子&&
o、 value1==value1&&
o、 value2==value2&&
ListQuals(o.deep,deep)&&
o、 浅==浅;
@凌驾
int get hashCode=>hashValues(值1、值2、hashList(深)、浅);
}
我说“菜谱”几乎是-1分,但既然你的问题质量很好,我就排第一。当然,你应该在标题中使用的术语是算法,甚至是“方法”(比如,好方法,或好算法),而不是“好食谱”。如果你觉得算法这个词听起来像是在炫耀,我可以理解。你可以说“way”,但下面使用“recipe”一词,也许可以从另一种语言中寻找具有任意精度整数的示例。我相信Smalltalk有这些,Dart的整数很有趣,因为它们在虚拟机上是任意的,但是如果你编译成JavaScript,你就会受到JavaScript的限制。所以你想要截断,有趣的问题是在哪里以及如何做到最好。这大概是移位/乘法、异或和截断的组合。这也是Smalltalk倾向于做的事情。魔鬼在于细节。我不知道Dart和Java有这么相似。特别是,它在处理整数类型方面有所不同,Java的公共哈希如果应用于大量事物,就会溢出到Javascript整数范围之外,这是不好的。Java ints溢出也是不好的。您可能希望使用dart:typed_数据包中的int32或int64,以便哈希代码保持一致。Javascript整数(以及编译为Javascript时的Dart整数)通过变为双精度溢出,这对于散列来说更糟糕。使用int32数据类型会有所帮助,但是dart:typed_数据没有单一的int类型,它只有集合。谢谢。这正是我要找的。记得添加quiver作为依赖项。在你的pubspec.yaml:quiver:'>=0.18.0难道hash2(姓名、年龄)
不够吗?添加import'包:quiver/core.dart'
forhash2()
不幸的是,当您使用提供程序时,这不适用于带有extends from ChangeNotifier的模型StateManagement@NiklasLehnfeld如果需要扩展另一个类,可以使用mixin。例如,class MyModel使用equalableMixin扩展了ChangeNotifier