Search code examples
darthashcode

What's a good recipe for overriding hashcode in Dart?


I find myself wanting to override hashcode and == for an object, and I'm wondering if there are best practices for how to implement a hashcode that depends on multiple attributes, and it seems like there are some Dart-specific considerations.

The simplest answer would be to XOR the hashes of all the attributes together, and it's probably not too bad. There's also an example in Dart Up and Running at 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;
 }

but that seems like it expects truncating integer semantics and in Dart overflowing the range of JS integers seems bad for hashing.

We could also do that and just truncate to 32 bits after each operation.

For my application the expected size of the set is very small and almost anything would do, but I'm surprised not to see a standard recipe for the general case. Does anyone have any experience or strong experience with this?


Solution

  • The quiver package provides helper functions hash2, hash3, etc., which simplify the task of implementing hashCode, with some assurance that it works properly under the Dart VM and when compiled to JavaScript.

    import 'package:quiver/core.dart';
    
    class Person {
      String name;
      int age;
    
      Person(this.name, this.age);
    
      @override
      bool operator ==(o) => o is Person && name == o.name && age == o.age;
    
      @override
      int get hashCode => hash2(name.hashCode, age.hashCode);
    }
    

    Also see this post for a slightly lengthier discussion.