gpt4 book ai didi

dart - Dart:类产生哈希码的奇怪行为

转载 作者:行者123 更新时间:2023-12-03 03:43:05 24 4
gpt4 key购买 nike

我在一个新类中有一个奇怪的行为,我必须重写==运算符和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检查是否相等,因此我可以理解,当遇到List作为主List的组件时,hashObjects使用List hashCode,而不是生成一个读取所有组件的新对象。我不明白的是为什么将Test和Test 2视为相等,而将List1和List2视为不相等。
这取决于我要为其创建哈希码的Iterable中有多少层内部List?
HashObjects的设计工作类似,还是应该将其视为错误?
我如何使用hashObjects有什么问题吗?

最佳答案

您的问题是hashObjects()不递归,空列表的两个不同实例通常具有不同的哈希值(除非两个都是const或偶然发生的)。

因此,hashObjects()可以像您期望的那样用于平面列表,但不能用于列表列表,除非各个子列表是相同的对象(并且不仅在结构上相等)。

以下示例应说明这一点:

import 'package:quiver/core.dart';

void main() {
var a = [];
var b = [];
var c = [];
print(a.hashCode); // different
print(b.hashCode);
print(hashObjects(a)); // both same, both zero
print(hashObjects(b));
print(hashObjects(a..add(1))); // both same
print(hashObjects(b..add(1)));
print(hashObjects(a..add(c))); // both same, because `c` is identical
print(hashObjects(b..add(c)));
print(hashObjects(a..add([]))); // different, because the two empty
print(hashObjects(b..add([]))); // lists are not identical.
}

关于dart - Dart:类产生哈希码的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46221539/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com