Dart Nuggets: Operator ==
To remove a class of annoying bug issue when dealing with equality of objects in dart, override the == operator in your custom models especially if you are going to be comparing objects of the same model.
void main() {
var obj1 = CustomObject(name: 'tope', age: 20);
var obj2 = CustomObject(name: 'tope', age: 20);
print(obj1 == obj2);
print(obj1.age == obj2.age);
print(obj1.name == obj2.name);
print(identical(obj1,obj2));}class CustomObject {
String name;
int age;
CustomObject({String name, int age}) {
this.name = name;
this.age = age;
}}
The above code will give the following response
false
true
true
false
So many times in code, to solve the issue
print(obj1.name == obj2.name && obj1.age == obj2.age); //true
This produces the correct response. There are 2 issues with this solution
- You have to repeat it everywhere you are checking for equality of the CustomObject instance.
- For complex objects, this can really become bloated very fast.
Solution
Override the == operator
void main() {
var obj1 = CustomObject(name: 'tope', age: 20);
var obj2 = CustomObject(name: 'tope', age: 20);
print(obj1.name == obj2.name && obj1.age == obj2.age);
print(obj1 == obj2);
print(obj1.age == obj2.age);
print(obj1.name == obj2.name);
print(identical(obj1,obj2));}class CustomObject {
String name;
int age;
CustomObject({String name, int age}) {
this.name = name;
this.age = age;
} @override
bool operator ==(Object x) {
return (x is CustomObject && x.name == name && x.age == age);
}
}
this results to
true
true
true
true
false
From now onward we can check for equality of instances of the CustomObject class and even adjust its meaning anytime in one place and this will work anywhere in code.
But there is an error message in the
Override `hashCode` if overriding `==`
What is the hashCode of an Object?
The hashCode of an object is not a concept that is unique to Dart. It can be found in other languages like Java.
A hashCode provides a numeric representation of an object’s contents so as to provide an alternate mechanism to loosely identify it.
By default, the hashCode is an integer that represents the internal memory. address of the object. So simply, it represents the identity of the object.
By default, the default operator == considers 2 object. as equal if their hashCode are equal i.e they are the same object.
This concept of identity equality based on hashCode is used to make HashSet and HashMap efficient.
So to make sure everything works at the original efficiency and consistency, you are advised to make sure changes to operator == are also reflected in hashCode and vice versa.
Thanks to this original article by Patrice Calin, we can easily ovveride the hashCode using the quiver package in pub.
http://pchalin.blogspot.com/2014/04/defining-equality-and-hashcode-for-dart.html
Final Solution
import 'package:quiver/core.dart';void main() {
var obj1 = CustomObject(name: 'tope', age: 20);
var obj2 = CustomObject(name: 'tope', age: 20);
print(identical(obj1,obj2));
print(obj1.name == obj2.name && obj1.age == obj2.age);
print(obj1 == obj2);
print(obj1.age == obj2.age);
print(obj1.name == obj2.name);
print(identical(obj1,obj2));
}class CustomObject {
String name;
int age;
CustomObject({String name, int age}) {
this.name = name;
this.age = age;
} @override
bool operator ==(Object x) {
return (x is CustomObject && x.name == name && x.age == age);
}
@override
int get hashCode => hash2(name.hashCode, age.hashCode);}
Output is
true
true
true
true
false
Note, in all of the samples print(identical(obj1,obj2)); returns false because. identity checks whether the two references are the same object so except you are checking the same instance, it will return false.
You will find the need for overriding the operator == in many places in software development where equality needs to be checked for objects.
Please I would really love to hear your feedback. follow me https://twitter.com/topeomot and https://github.com/topeomot2