首页 > 解决方案 > 为什么集合不包含点

问题描述

我有一个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

我在这里哪里出错了?

标签: dart

解决方案


Set<Point<double>>.identity()使用身份哈希进行比较。但是Point通过 x 和 y 的相等性覆盖了比较(参见源代码)

所以在这种情况下a.idenityHash != a.hashcodea.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

推荐阅读