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) andhashCode
methods for your class based on selected fields. - package:freezed: This package is great for creating immutable data classes and automatically handles
==
andhashCode
generation among other things.
Using one of these methods makes handling object comparison much simpler and less error-prone.