dart - 为什么集合不包含点
问题描述
我有一个Set<Point<double>>
并且我想测试该集合是否包含特定的Point<double>
.
我的理解是,如果两个Point<double>
实例hashCode
根据 具有相同且相等==
,则默认Set
实现认为它们相同,并且true
当其中一个点在集合中并且我们使用 测试另一个点时将返回contains
。
但在以下示例中,情况似乎并非如此:
import 'dart:math';
void main() {
final points = Set<Point<double>>.identity();
final a = Point<double>(5, 2);
final b = Point<double>(5, 2);
points.add(a);
print("a == b ? ${a == b}");
print("a.hashCode == b.hashCode ? ${a.hashCode == b.hashCode}");
print("points.contains(a) ? ${points.contains(a)}");
print("points.contains(b) ? ${points.contains(b)}");
}
根据 DartPad的输出是:
a == b ? true
a.hashCode == b.hashCode ? true
points.contains(a) ? true
points.contains(b) ? false
我在这里哪里出错了?
解决方案
Set<Point<double>>.identity()
使用身份哈希进行比较。但是Point
通过 x 和 y 的相等性覆盖了比较(参见源代码)
所以在这种情况下a.idenityHash != a.hashcode
,a.idenityHash != b.idenityHash
即使a.hashCode == b.hashCode
. 这一切都发生了,因为==
并且hashCode
被坐标覆盖以进行对象比较。
因此,如果您创建使用 hashCode 方法进行比较的普通集,您会得到预期的结果
final points = Set<Point<double>>();
points.add(a);
print("points.contains(b) ? ${points.contains(b)}"); // true