Dart Nuggets: Operator ==

Temitope Omotunde
3 min readJun 28, 2020

--

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

--

--

Temitope Omotunde
Temitope Omotunde

No responses yet