DART / CHAPTER 08
Value equality and stable hash keys
AdvancedKeep equality, hashing, and mutation consistent.
By the end of this chapter
- Distinguish identity from value equality
- Pair equality overrides with hashCode
- Keep hashed key fields stable
The idea
A domain value may need equality based on its fields rather than object identity. When overriding operator ==, define a consistent equivalence relation and provide a matching hashCode: equal objects must have equal hash codes. Unequal objects may share a hash code, so hashing is an indexing aid rather than a proof of inequality or identity.
Hash-based sets and maps rely on a key’s equality and hash behavior remaining stable while it is stored. Mutating fields used in equality can make lookup behave unexpectedly. Prefer immutable value fields for such keys, or remove and reinsert a key around a deliberate change. Test equal-but-distinct instances, unequal instances, and set deduplication rather than checking only an object against itself.
class Key {
final int id;
const Key(this.id);
@override bool operator ==(Object other) => other is Key && other.id == id;
@override int get hashCode => id.hashCode;
}
void main() { print({Key(2),Key(2),Key(3)}.length); }2
Two distinct keys with id two compare equal and hash consistently, so the set retains two logical values.
Try it yourself
Define an immutable two-field value key and test equality and set deduplication.
Use your own editor for this exercise. Runnable challenges on CodeQuest are available for JavaScript, Python, and SQL.
CHECK YOUR UNDERSTANDING