在Dart中覆盖哈希码的好方法是什么?

时间:2013-12-13 23:15:22

标签: dart hashcode

我发现自己想要覆盖对象的哈希码和==,我想知道是否有关于如何实现依赖于多个属性的哈希码的最佳实践,并且似乎有一些特定于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位。

对于我的应用程序,预期的集合大小非常小,几乎任何事情都可以,但我很惊讶没有看到一般情况的标准配方。有没有人对此有任何经验或丰富经验?

6 个答案:

答案 0 :(得分:24)

quiver package提供帮助函数hash2hash3等,这简化了实现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

Flutter API docs for hashValues

Flutter API docs for 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];
}