web-dev-qa-db-ja.com

Dartでハッシュコードをオーバーライドするための良いレシピは何ですか?

オブジェクトのハッシュコードと==をオーバーライドしたいと思っています。複数の属性に依存するハッシュコードを実装するためのベストプラクティスがあるかどうか疑問に思っています。また、ダート固有の考慮事項があるようです。

最も簡単な答えは、XORすべての属性のハッシュをまとめたものであり、おそらくそれほど悪くはありません。DartUpand Runningに例があります https:// www .dartlang.org/docs/Dart-up-and-running/contents/ch03.html

  // 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ビットに切り捨てることもできます。

私のアプリケーションでは、セットの予想サイズは非常に小さく、ほとんど何でもできますが、一般的なケースの標準レシピが表示されないことに驚いています。誰かがこれについて何か経験や強い経験を持っていますか?

31
Alan Knight

quiverパッケージ はヘルパー関数を提供しますhash2hash3など。これにより、hashCodeを実装するタスクが簡素化され、Dart VMandJavaScriptにコンパイルした場合。

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

少し長い議論については、 この投稿 も参照してください。

28
Patrice Chalin

DartはJavaに非常に似ているため、Dartにも適用できるJavaのhashCodesに関する適切なリファレンスを確実に見つけることができます。

少しグーグルすると、私は JavaのObject.hashCode() に関するウィキペディアのページに移動しました。単純なオブジェクトのハッシュコードの非常に基本的な例があります。一般的な方法は、素数(異なる数)を使用して乗算を実行し、オブジェクトの各プロパティに値を追加することです。

この質問 f.e. String.hashCode()メソッドの乗算に数値31が選択される理由を説明します。

ハッシュコード実装のより詳細な例は、Googleを使用して簡単に見つけることができます。

1
Steven Roose

良い答えではありませんが、これを提供するための未解決のバグがあります https://code.google.com/p/Dart/issues/detail?id=11617 および "Jenkins SMI hash "は、公開されていれば使用するのが最善のようです。

1
Alan Knight