pub repository
mirror.p-hatan.irequatable
2.1.0A Dart package that helps to implement value based equality without needing to explicitly override == and hashCode.
Readme
Overview
Being able to compare objects in Dart often involves having to override the == operator as well as hashCode.
Not only is it verbose and tedious, but failure to do so can lead to inefficient code which does not behave as we expect.
By default, == returns true if two objects are the same instance.
Let's say we have the following class:
class Person {
const Person(this.name);
final String name;
}
We can create instances of Person like so:
void main() {
final Person bob = Person("Bob");
}
Later if we try to compare two instances of Person either in our production code or in our tests we will run into a problem.
print(bob == Person("Bob")); // false
For more information about this, you can check out the official Dart Documentation.
In order to be able to compare two instances of Person we need to change our class to override == and hashCode like so:
class Person {
const Person(this.name);
final String name;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is Person &&
runtimeType == other.runtimeType &&
name == other.name;
@override
int get hashCode => name.hashCode;
}
Now if we run the following code again:
print(bob == Person("Bob")); // true
it will be able to compare different instances of Person.
You can see how this can quickly become a hassle when dealing with complex classes. This is where Equatable comes in!
What does Equatable do?
Equatable overrides == and hashCode for you so you don't have to waste your time writing lots of boilerplate code.
There are other packages that will actually generate the boilerplate for you; however, you still have to run the code generation step which is not ideal.
With Equatable there is no code generation needed and we can focus more on writing amazing applications and less on mundane tasks.
Usage
First, we need to do add equatable to the dependencies of the pubspec.yaml
dependencies:
equatable: ^2.0.0
Next, we need to install it:
# Dart
pub get
# Flutter
flutter packages get
Lastly, we need to extend Equatable
import 'package:equatable/equatable.dart';
class Person extends Equatable {
const Person(this.name);
final String name;
@override
List<Object> get props => [name];
}
When working with json:
import 'package:equatable/equatable.dart';
class Person extends Equatable {
const Person(this.name);
final String name;
@override
List<Object> get props => [name];
factory Person.fromJson(Map<String, dynamic> json) {
return Person(json['name']);
}
}
We can now compare instances of Person just like before without the pain of having to write all of that boilerplate.
Note: Equatable is designed to only work with immutable objects so all member variables must be final (This is not just a feature of Equatable - overriding a hashCode with a mutable value can break hash-based collections).
Equatable also supports const constructors:
import 'package:equatable/equatable.dart';
class Person extends Equatable {
const Person(this.name);
final String name;
@override
List<Object> get props => [name];
}
Equatable also supports nullable props:
import 'package:equatable/equatable.dart';
class Person extends Equatable {
const Person(this.name, [this.age]);
final String name;
final int? age;
@override
List<Object?> get props => [name, age];
}
toString Implementation
Equatable can implement toString method including all the given props. If you want that behaviour for a specific Equatable object, just include the following:
@override
bool get stringify => true;
For instance:
import 'package:equatable/equatable.dart';
class Person extends Equatable {
const Person(this.name);
final String name;
@override
List<Object> get props => [name];
@override
bool get stringify => true;
}
For the name Bob, the output will be:
Person(Bob)
This flag by default is false and toString will return just the type:
Person
EquatableConfig
stringify can also be configured globally for all Equatable instances via EquatableConfig
EquatableConfig.stringify = true;
If stringify is overridden for a specific Equatable class, then the value of EquatableConfig.stringify is ignored.
In other words, the local configuration always takes precedence over the global configuration.
Note: EquatableConfig.stringify defaults to true in debug mode and false in release mode.
Recap
Without Equatable
class Person {
const Person(this.name);
final String name;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is Person &&
runtimeType == other.runtimeType &&
name == other.name;
@override
int get hashCode => name.hashCode;
}
With Equatable
import 'package:equatable/equatable.dart';
class Person extends Equatable {
const Person(this.name);
final String name;
@override
List<Object> get props => [name];
}
Mixin Usage
Sometimes it isn't possible to extend Equatable because your class already has a superclass.
In this case, you can still get the benefits of Equatable by using Equatable as a mixin.
Usage
Let's say we want to make an EquatableDateTime class, we can use Equatable like so:
class EquatableDateTime extends DateTime with Equatable {
EquatableDateTime(
int year, [
int month = 1,
int day = 1,
int hour = 0,
int minute = 0,
int second = 0,
int millisecond = 0,
int microsecond = 0,
]) : super(year, month, day, hour, minute, second, millisecond, microsecond);
@override
List<Object> get props {
return [year, month, day, hour, minute, second, millisecond, microsecond];
}
}
Now if we want to create a subclass of EquatableDateTime, we can just override props.
class EquatableDateTimeSubclass extends EquatableDateTime {
final int century;
EquatableDateTimeSubclass(
this.century,
int year,[
int month = 1,
int day = 1,
int hour = 0,
int minute = 0,
int second = 0,
int millisecond = 0,
int microsecond = 0,
]) : super(year, month, day, hour, minute, second, millisecond, microsecond);
@override
List<Object> get props => [...super.props, century];
}
Benchmarks
You can see and run performance benchmarks by heading over to benchmarks.
Maintainers
Changelog
2.1.0
- feat: deprecate
EquatableMixin(#214)class Foo with EquatableMixin {...} // OLD class Foo with Equatable {...} // NEW - refactor: update analysis options
- deps: upgrade to Dart >=3.0.0
- chore(example): upgrade to Dart >=3.12.0
2.0.8
- chore: bump license year (#208)
- fix:
mapEqualswhen comparing maps with different keys and null values (#207)
2.0.7
2.0.6
- perf: improve equality comparison performance (#173)
- docs: improve snippet in
README(#184) - chore: upgrade example to Dart >=3.5.0
- chore: add funding and topics to
pubspec.yaml(#176) - chore: add performance benchmarks
- chore: fix typo in inline API docs (#170)
- refactor: simplify
toStringlogic (#140) - docs: add nullable props example to
README - refactor: update
analysis_options.yaml(#169) - fix: add
@immutabletoEquatableMixin(#154)
2.0.5
- fix: resolves
T not a subtype of type 'Comparable<dynamic>'when computinghashCode
2.0.4
- fix: use
SplayTreeSetto resolve inconsistenthashCodefor properties of typeSet(#142)
2.0.3
- fix: revert
EquatableMixin== to useObject(#122)
2.0.2
- fix:
Mapprop with non-comparable key
2.0.1
- fix:
hashCodeshould be the same for equal objects (Mapfix)
2.0.0
- BREAKING: opt into null safety
- feat!: upgrade Dart SDK constraints to
>=2.12.0-0 <3.0.0
- feat!: upgrade Dart SDK constraints to
- BREAKING: stringify prints "null" for null properties instead of ""
- feat:
EquatableConfig.stringifydefaults totruein debug mode. - fix: support legacy equality overrides with
EquatableMixin - fix: iterable equality comparisons (#101)
- fix: stringify instance with long properties (#94)
- chore: update dependencies
collection: ^1.15.0meta: ^1.3.0
- docs: minor updates to
READMEandexample
2.0.0-nullsafety.4
- feat:
EquatableConfig.stringifydefaults totruein debug mode. - fix: support legacy equality overrides with
EquatableMixin
2.0.0-nullsafety.3
- chore: update dependencies
collection: ^1.15.0meta: ^1.3.0
2.0.0-nullsafety.2
2.0.0-nullsafety.1
- BREAKING: stringify prints "null" for null properties instead of ""
2.0.0-nullsafety.0
- BREAKING: opt into null safety
- feat!: upgrade Dart SDK constraints to
>=2.12.0-0 <3.0.0 - docs: minor updates to
READMEandexample
1.2.6
1.2.5
- docs: dartdoc improvements (#80)
- docs: minor inline documentation improvements
1.2.4
- fix:
EquatableMixinstringify respectsEquatableConfig.stringify(#81)
1.2.3
- docs: inline, public documentation improvements (#78).
- refactor: stricter analysis/lint rules
1.2.2
- Documentation badge fixes and updates
1.2.1
- Fix
hashCodecomputation forIterables(#74) - Minor documentation improvements
1.2.0
- Added
EquatableConfigfor globalstringifyconfiguration (#69)
1.1.1
- Updates to
EquatableUtilsdocumentation
1.1.0
- Fix
hashCodeerror whenpropsisnull(#45) - Added
stringifyfeature (optionaltoStringoverride) (#45)
1.0.3
- Fix
hashCodecollisions for lists within props (#53)
1.0.2
- Fix internal lint warnings
1.0.1
- Fix
hashCodecollisions withMapproperties (#43)
1.0.0
- Update hashCode implementation to use
Jenkins Hash(#39) - Documentation Updates
0.6.1
- Minor documentation updates
0.6.0
- The
propsgetter override is required for bothEquatableandEquatableMixin - Performance Improvements
0.5.1
- Allow const constructors on
Equatableclass
0.5.0
- Removed
EquatableMixinBase(now covered byEquatableMixin). - Typed
EquatableMixinfromList<dynamic>toList<Object>to fix linter issues withimplicit-dynamic: false.
0.4.0
Update toString to default to runtimeType (#27)
0.3.0
Enforce Immutability (#25)
0.2.6
Improved support for collection types (#19)
0.2.5
Improved support for Iterable, List, Map, and Set props (#17)
0.2.4
Additional Minor Documentation Updates
0.2.3
Documentation Updates
0.2.2
Bug Fixes:
Equatableinstances that are equal now have the samehashCode(#8)
0.2.1
Update Dart support to >=2.0.0 <3.0.0
0.2.0
Add EquatableMixin and EquatableMixinBase
0.1.10
Enhancements to toString override
0.1.9
equatable has 0 dependencies
0.1.8
Support Iterable props
0.1.7
Added toString override
0.1.6
Documentation Updates
- Performance Tests
0.1.5
Additional Performance Optimizations & Documentation Updates
0.1.4
Performance Optimizations
0.1.3
Bug Fixes
0.1.2
Additional Updates to Documentation.
- Logo Added
0.1.1
Minor Updates to Documentation.
0.1.0
Initial Version of the library.
- Includes the ability to extend
Equatableand not have to override==andhashCode.
Installing
export PUB_HOSTED_URL=https://pub.mirror.p-hatan.ir
flutter pub add equatablepubspec.yaml
name: equatable
description: A Dart package that helps to implement value based equality without needing to explicitly override == and hashCode.
version: 2.1.0
repository: https://github.com/felangel/equatable
issue_tracker: https://github.com/felangel/equatable/issues
homepage: https://github.com/felangel/equatable
documentation: https://github.com/felangel/equatable
topics: [equality, equals]
funding: [https://github.com/sponsors/felangel]
environment:
sdk: ">=3.0.0 <4.0.0"
dependencies:
collection: ^1.0.0
meta: ^1.0.0
dev_dependencies:
test: ^1.0.0
screenshots:
- description: The equatable package logo.
path: doc/assets/equatable_logo.png
Version history
| Version | Published | Archive | SHA-256 |
|---|---|---|---|
| 0.1.0 | 2019-01-06T19:33:39.650855Z | Download | ca67495ceda4194a6ea27f7dde7b588c1fb2719fa304e047b182054207472d7c |
| 0.1.1 | 2019-01-06T19:44:47.595857Z | Download | dc8bb0e1e92b65749fe69d82b7fb10f0460f5fb95a558dbec05c957e2e68a1c4 |
| 0.1.2 | 2019-01-07T02:54:34.027077Z | Download | 544ccbaddb78dd32a37484222a57cab18f718e43da4809bbea334f7b87d9ec16 |
| 0.1.3 | 2019-01-07T19:54:09.582363Z | Download | 26ab9f9e9dc9419a3b81080d218cd0c04905e4132fbd24e502024afb4e085fcf |
| 0.1.4 | 2019-01-07T20:26:44.769580Z | Download | d378b5ba7f806719dd456e46e08ed625ee88048fab06b46093abe2008b615730 |
| 0.1.5 | 2019-01-07T21:17:02.141357Z | Download | 3e268d04e9d66a02678820ff8a69dcdd271992f3e5d99573c9bcc0e9034e4c6a |
| 0.1.6 | 2019-01-10T04:49:01.592626Z | Download | 034cd78031e48e1d9d9bd5e6a8edf40ae4007ee7c2404bac21c00b5e6df1a860 |
| 0.1.7 | 2019-01-23T18:24:13.705448Z | Download | 14cf3af507649011796994ae3940e1a99ea8f3f417679b61918bdaad91e9ca5b |
| 0.1.8 | 2019-01-23T20:18:37.000130Z | Download | bfbb2d743fe32086f4a741940ca3c2ce4236e095d65d29ba2369b1523bce7772 |
| 0.1.9 | 2019-01-24T23:35:18.206844Z | Download | 3ddd6fd47751a3866e79ae5d189ce3900051e76240e1b6125f13cd805b22383c |
| 0.1.10 | 2019-01-26T20:34:30.897192Z | Download | b15487c8a57b12d2ad3bb15f13c637384fbc66704b853542615b4a5623b1ad27 |
| 0.2.0 | 2019-02-21T02:19:40.842737Z | Download | 3d088bcd4abb0f72e0ff7fbd423955689b21c1bd39767dc5d55ecf56f01292d0 |
| 0.2.1 | 2019-02-25T00:42:19.844636Z | Download | 2f404fd722e372506e8e6dd269cd3dd19b35b054c3d99df2200947931c363918 |
| 0.2.2 | 2019-02-26T05:56:31.612527Z | Download | 3698192288f0cfc67b7edcb776addde99126c022285d635ee973c4a02132a0d8 |
| 0.2.3 | 2019-03-09T15:56:04.684233Z | Download | 3e7f49ce4bc5f6edfc0fd3e2fd60d598263f439b6431ce45d4541bd3a26095b2 |
| 0.2.4 | 2019-05-19T03:10:18.260475Z | Download | bc5fbad0c8b634870d32b9d3ee8f15f4a9c0f9dd1d20931d66429cb7055555d5 |
| 0.2.5 | 2019-05-24T20:28:49.674727Z | Download | 0a1d7e4613c5765174635f333ca269a35141b8ea177d90458067f98e83ba66cb |
| 0.2.6 | 2019-05-31T21:29:21.394631Z | Download | 25b1afe7adb5194994a90bf7e01dacbf93f3bfbbc1272413e6fb686861163e60 |
| 0.3.0 | 2019-07-15T05:04:54.123081Z | Download | 0f8be44d0f65630199b75090fdb27c95f6fbf939ef2a13f3ecc2d1a93c3f64b9 |
| 0.4.0 | 2019-08-04T19:34:37.127112Z | Download | e96061e0641a49edd48d3eaca0f9af6369a4630f5e2cbae41964914417aa27fb |
| 0.5.0 | 2019-08-26T09:27:23.905907Z | Download | 5eda445d364a6f90fcfdd4252d33ccb979f912324a7571b6dcd8370c9a926448 |
| 0.5.1 | 2019-08-29T14:43:18.136444Z | Download | f109066e13847e138b16a52f0fa774c36aede702083c354dec50f499db2a8dc8 |
| 0.6.0 | 2019-09-27T02:44:44.168407Z | Download | 6a0e2c6b436ed1687d43428beceec06b2e5bd606849c9bf745cb22539c01d4e9 |
| 0.6.1 | 2019-10-02T01:54:11.508011Z | Download | 4c12553fbff9c208376811965915b1b3350dc15cea823ee11cfe5952a5d498e1 |
| 1.0.0 | 2019-11-19T02:11:50.231815Z | Download | e9c2e65822a1780c9288c162272d94749644d41d8a28ac1399b8f6ef0b0a21c0 |
| 1.0.1 | 2019-11-24T07:15:53.595264Z | Download | 426f31d6895e1be8dbf0f881a447945255c1211dc62f64b3bc620e57e699c461 |
| 1.0.2 | 2020-01-03T20:57:52.093232Z | Download | 622a9c050f4e5575778fa8c44390b951426d2af7f50c5edfb66eec29b9c4299e |
| 1.0.3 | 2020-01-24T23:25:58.866218Z | Download | 5b5eaa48fecc288e0d5b7ea1d49a95124c54c369a8b9a65aed84847778209b6f |
| 1.1.0 | 2020-02-10T15:03:03.036428Z | Download | 6df0c8b91eb4f95ba751678143743687b00ac9c639b2352a0623c5871fb5f927 |
| 1.1.1 | 2020-03-02T21:29:56.642636Z | Download | cab4ec7b49b16c6d4a2640e966959a88f68198dc5479e69365b8aeb2ad0e2a36 |
| 1.2.0 | 2020-05-29T16:53:39.353519Z | Download | cc5e9c6ec7a339d9aab41593005444a460c7e3f68988de527af9dcd5e0d5ca31 |
| 1.2.1 | 2020-07-11T03:00:29.967848Z | Download | 121ae72b249a031a2bdd0c10f5a9d36e8ba6ca25622268db5f8990922a03a29d |
| 1.2.2 | 2020-07-11T03:05:31.918170Z | Download | ddb07d0fe0a37dfccb78ddf4f43f3e7c7dc6ca7510eefb4d2424c51f70ac2803 |
| 1.2.3 | 2020-07-25T16:07:41.708590Z | Download | 0ea812105d082f4b445cd2cc6d3f9831ae3a30614229d94ed6ef3412e3123e84 |
| 1.2.4 | 2020-08-23T04:29:04.293622Z | Download | e43d1f19c51c252d4eea6c94f6f2a54369bc2a76449837dc31a04cc688819c35 |
| 1.2.5 | 2020-09-08T16:23:49.060322Z | Download | 6d80ee2eda2a2a37646cb28b9e8292dcd1256e3b3eeafdd5693b843c055513fc |
| 1.2.6 | 2021-02-08T05:33:57.003432Z | Download | 8007a033720c056066dd1dc20bc2934cac91e271f0408c578aa26c7731618a03 |
| 2.0.0-nullsafety.0 | 2020-11-22T04:24:16.638146Z | Download | 8781f93bd81f563a4afaf8ffe4c3bd84bc8f4d3beef810fed67fa513583e8ba4 |
| 2.0.0-nullsafety.1 | 2021-01-06T06:00:28.443739Z | Download | d6c954254d63f4ef225ac65c0c3d0ff3b99dba6cc27f7d9467f5cdd68480675d |
| 2.0.0-nullsafety.2 | 2021-02-08T05:49:42.671063Z | Download | 538d7f4bfc401b38920f5feb7447314dc494baf90458fd5b181fd3f3e93f2adc |
| 2.0.0-nullsafety.3 | 2021-02-08T05:54:51.865286Z | Download | 71fde743286a9c659c0e25abededb0d3653e7ecb1daf3d1cad250f7914d892ee |
| 2.0.0-nullsafety.4 | 2021-02-26T16:43:09.085949Z | Download | d8033f6bc7bdf7a3b0b8999bb76380990460d2dfcc844b9a75e03d39faeaee33 |
| 2.0.0 | 2021-03-02T05:37:50.767881Z | Download | 8867afc0f09dd9aff976817fbd94e9a35a3a2e58bef3b39a5376918321ec97a4 |
| 2.0.1 | 2021-05-19T16:53:39.155448Z | Download | 14263956beb86652e90cd397253539aad99c05780513e46033fb4ee5c4074384 |
| 2.0.2 | 2021-05-20T04:13:24.955901Z | Download | da851e4d8b36afbc98f11b65f6d12a72b9061f93b74327777565d978649d81cb |
| 2.0.3 | 2021-06-14T21:48:24.918544Z | Download | c6094fd1efad3046334a9c40bee022147e55c25401ccd89b94e373e3edadd375 |
| 2.0.4 | 2022-08-19T02:47:56.449056Z | Download | 42d13ad51bd7b1a50ce2b3dc39150ad9fd26a803856004904804bb5fa096feb7 |
| 2.0.5 | 2022-08-19T13:56:14.122054Z | Download | c2b87cb7756efdf69892005af546c56c0b5037f54d2a88269b4f347a505e3ca2 |
| 2.0.6 | 2024-11-21T04:06:27.320789Z | Download | b35578f687b79243d39008c44d638474d93e9091e578c970efef41ce0c3fa000 |
| 2.0.7 | 2024-11-21T18:14:17.546841Z | Download | 567c64b3cb4cf82397aac55f4f0cbd3ca20d77c6c03bedbc4ceaddc08904aef7 |
| 2.0.8 | 2026-01-04T21:45:18.944527Z | Download | 3e0141505477fd8ad55d6eb4e7776d3fe8430be8e497ccb1521370c3f21a3e2b |
| 2.1.0-dev.0 | 2026-05-24T19:47:18.390586Z | Download | f8b1ad1d299796e7bd23f576985f1b3649438e402833636af675e127e0c42dc0 |
| 2.1.0 | 2026-07-05T05:06:30.203061Z | Download | 3bce007a596ff8b3119c45d68aaef631272537c03d30e5d4534dd24bf4c5eaa2 |
| 3.0.0-dev.0 | 2024-10-16T02:06:20.810131Z | Download | 4f531ad0dc4076cab07fec5ef112d6244c217cc97c2c211d5a27f3e20783980a |
| 3.0.0-dev.1 | 2024-10-16T02:48:11.270890Z | Download | 0b8e50fa31b269cc82a8442f1f7da4a425a16aa5be6a951600daa660a8653198 |
| 3.0.0 | 2026-09-15T20:11:31.188136Z | Download | ea36e500cbf0ec18361deabca755434f73e42fe53c5130021c7e2d6b5ebe1702 |
Dependencies
collection "^1.0.0"
meta "^1.0.0"