Understanding Equals and Hashcode
When working with Dart objects, you sometimes need to check if two objects are the same or represent the same value. Dart provides the == operator for equality checks and a hashCode property.
By default, == checks if two variables refer to the exact same instance in memory. The default hashCode is based on the instance identity.
However, for many custom classes, you want == to check if two different instances have the same value (like having the same name for a Person object).
Why Overriding is Important
A hash code is a number linked to each object. It's super useful for data structures like HashMap and HashSet. These structures use the hash code to quickly find objects.
If you override == to check for value equality but don't override hashCode, things can go wrong. Objects that you consider equal by your == logic might end up in different places in a HashMap because they have different default hash codes. This breaks the contract that if two objects are equal (a == b is true), their hash codes must be the same (a.hashCode == b.hashCode).
So, to compare two instances of a class like Person based on their properties (like name), you need to override both == and hashCode.
Example: The Person Class
Here's how you might override == and hashCode for a simple Person class:
class Person {
const Person(this.name);
final String name;
bool operator ==(Object other) =>
identical(this, other) ||
other is Person &&
runtimeType == other.runtimeType &&
name == other.name;
int get hashCode => name.hashCode;
}
In this example, two Person objects are considered equal if they are the exact same instance (identical(this, other)) OR if the other object is also a Person, has the same type, and their name properties are the same.
The hashCode is calculated simply using the hash code of the name property.
How to Generate it Easily
Writing these overrides manually can be tedious. Luckily, there are easier ways:
- package:equatable: This package helps you implement value equality without writing the boilerplate code yourself.
- IntelliJ or Android Studio: These IDEs often have built-in options to automatically generate
equals(or==in Dart) andhashCodemethods for your class based on selected fields. - package:freezed: This package is great for creating immutable data classes and automatically handles
==andhashCodegeneration among other things.
Using one of these methods makes handling object comparison much simpler and less error-prone.