【发布时间】:2017-09-14 14:18:05
【问题描述】:
我在一个新类中遇到了一个奇怪的行为,我必须在其中重写 == 运算符和 hashCode 方法。
我会给你举个例子。 假设我们有一个如下所示的 Test 类:
import 'package:quiver/core.dart';
import 'package:collection/collection.dart';
class Test {
List testList = [];
operator ==(Object other) {
if (other is! Test) return false;
Function deepEq = const DeepCollectionEquality.unordered().equals;
return deepEq(testList, (other as Test).testList);
}
int get hashCode => hashObjects(testList);
}
现在我运行以下代码:
main() {
Test test = new Test();
//test.testList.add([]);
print('Test, hash: ${test.hashCode}');
Test test_2 = new Test();
//test_2.testList.add([]);
print('Test_2, hash: ${test_2.hashCode}');
print("is ${test == test_2} that Test and Test2 are equal");
Function deepEq = const DeepCollectionEquality.unordered().equals;
bool b = deepEq(test, test_2);
print("is $b that Test and Test2 are deep equal");
List l1 = [test];
print('L1 hash: ${l1.hashCode}');
List l2 = [test_2];
print('L2 hash: ${l2.hashCode}');
deepEq = const DeepCollectionEquality.unordered().equals;
b = deepEq(l1, l2);
print("is $b that List1 and List2 are deep equal");
}
上面的代码打印出以下内容,这正是我所期望的:
Test, hash: 0
Test_2, hash: 0
is true that Test and Test2 are equal
is true that Test and Test2 are deep equal
L1 hash: 89819481
L2 hash: 414841104
is true that List1 and List2 are deep equal
现在如果我取消注释这些行:
test.testList.add([]);
test_2.testList.add([]);
重新运行程序,结果如下:
Test, hash: 76603616
Test_2, hash: 386421917
is true that Test and Test2 are equal
is true that Test and Test2 are deep equal
L1 hash: 915458568
L2 hash: 503799923
is false that List1 and List2 are deep equal
这不是我所期望的。鉴于 DeepCollectionEquality 内部使用 hashCode 来检查相等性,我可以理解 hashObjects 在遇到作为主 List 的组件的 List 时使用 List hashCode,而不是生成一个读取所有组件的新哈希码。我不明白为什么 Test 和 Test 2 被认为是相等的,而 List1 和 List2 不是。 这取决于我为其创建哈希码的 Iterable 中存在多少级别的内部列表? HashObjects 是这样设计的,或者这应该被认为是一个错误? 我使用 hashObjects 的方式有问题吗?
【问题讨论】: