I have a class
class Foo {
final List<int> a;
final List<int> b;
Foo(this.a, this.b);
@override
bool operator ==(Object other) => identical(this, other) || other is Foo && listEquals(a, other.a) && listEquals(b, other.b);
@override
int get hashCode => Object.hash(a, b);
}
I want to check if two instances of Foo are equal with hashCodes.
final list1 = Foo([0], [0]);
final list2 = Foo([0], [0]);
print(list1 == list2); // Prints true, all good
print(list1.hashCode == list2.hashCode); // Prints false.
How to properly override hashCode so that the above print statement also prints true without using a third party package?
CodePudding user response:
You could use the hashAll method to hash a list of all of your objects:
int get hashCode => Object.hashAll([...a, ...b]);
This should get you the result you want.
void main() {
List<int> a1 = [0];
List<int> a2 = [1];
List<int> b1 = [0];
List<int> b2 = [1];
final simpleHashA = Object.hash(a1, a2);
final simpleHashB = Object.hash(b1, b2);
final correctHashA = Object.hashAll([...a1, ...a2]);
final correctHashB = Object.hashAll([...b1, ...b2]);
print(simpleHashA == simpleHashB); // prints false
print(correctHashA == correctHashB); // prints true
}
CodePudding user response:
Wherever you got the the listEquals method from, should also provide you with a compatible listHash function. If it doesn't, you cab use ListEquality from package:collection, it also has a hashCode method.
Then you can do:
int get hashCode => Object.hash(
const ListEquality().hash(a),
const ListEquality().hash(b));
