Summary: in this tutorial, you’ll learn about object identity & equality and how to implement object equality properly.
Object identity
In Dart, all classes implicitly inherit from the Object
class directly or indirectly. Therefore, all classes can access the ==
operator from the Object
class.
The ==
operator returns true
if two objects are equal. By default, the ==
operator compares two objects by their identities. For example:
class Point {
int x;
int y;
Point({required this.x, required this.y});
}
void main() {
var p1 = Point(x: 10, y: 20);
var p2 = Point(x: 10, y: 20);
var result = p1 == p2;
print(result);
}
Code language: JavaScript (javascript)
Output:
false
Code language: JavaScript (javascript)
How it works.
- First, define a
Point
class with two propertiesx
andy
. - Second, create two instances of the
Point
classp1
andp2
with the samex
andy
values. - Third, use the
==
operator to comparep1
withp2
. Even thoughp1
andp2
have the samex
andy
coordinates, they are not equal. The reason is thatp1
andp2
are different objects.
In fact, p1
and p2
are variables that reference separate objects that have the same x
and y
values. To check if two variables reference the same object, you use the identical()
function.
For example, the following returns false
because p1
and p2
reference different Point
objects:
var p1 = Point(x: 10, y: 20);
var p2 = Point(x: 10, y: 20);
var result = identical(p1, p2);
print(result);
Code language: PHP (php)
However, the following returns true
because p1
and p2
reference the same object:
var p1 = Point(x: 10, y: 20);
var p2 = p1;
var result = identical(p1, p2);
print(result);
Code language: PHP (php)
Object equality
If you want two Point
objects with the same x
and y
to be equal, you need to override the ==
operator in the Point
class. For example:
class Point {
int x;
int y;
Point({required this.x, required this.y});
@override
operator ==(o) => o is Point && o.x == x && o.y == y;
}
void main() {
var p1 = Point(x: 10, y: 20);
var p2 = Point(x: 10, y: 20);
var result = p1 == p2;
print(result);
}
Code language: JavaScript (javascript)
Output:
true
Code language: JavaScript (javascript)
In this example, the operator ==
returns true
if two objects are the instances of the Point
class and have the same x
and y
values.
All Dart classes have a getter hashCode
. By rules, if two objects are equal, their hash codes (or values) should be equal. As a developer, you need to preserve this rule.
In practice, if you override the ==
operator, you should also override the hashCode
getter because they’re interrelated.
To calculate the hash of multiple values, you can use the Object.hash()
static method. For example, the following Point
class overrides both the ==
operator and hashCode
getter:
class Point {
int x;
int y;
Point({required this.x, required this.y});
@override
operator ==(o) => o is Point && o.x == x && o.y == y;
@override
int get hashCode => Object.hash(x, y);
}
void main() {
var p1 = Point(x: 10, y: 20);
var p2 = Point(x: 10, y: 20);
var result = p1 == p2;
print(result);
print('p1: ${p1.hashCode}, p2: ${p2.hashCode}');
}
Code language: JavaScript (javascript)
Output:
true
p1: 68682774, p2: 68682774
Code language: JavaScript (javascript)
Summary
- By default, the
==
operator returns true if two variables reference the same object. It compares objects by their identities. - Use the
identical()
function to check if two objects are the same. - Override the
==
operator to implement custom logic for checking object equality. - If two objects are equal, their hash code should be equal. Therefore, you should also override the
hashCode
getter when overriding the==
operator.