Dart中自定义类集合(Set)交集操作失效问题
为什么自定义类的Set交集返回空集合?
这个问题的核心在于Dart中Set判断元素相等的默认逻辑——它是基于对象引用来判断的,而不是你期望的对象内容匹配。
你看,你创建的两个Item(id: 1, name: "carrot")看起来内容完全一样,但它们是内存中独立的两个对象实例。Set的intersection方法默认会把这种引用不同的实例判定为不同元素,所以最终交集结果就是空集合了。
解决方案:自定义相等判断规则
要让Set根据id和name的内容来判断元素是否相等,你需要为Item类重写==运算符和hashCode属性(这两者必须同时重写,因为Dart要求相等的对象必须拥有相同的哈希值,否则Set的哈希表逻辑会失效)。
手动重写的实现方式
修改你的Item类:
class Item { int id; String name; Item({required this.id, required this.name}); @override bool operator ==(Object other) { // 如果是同一个对象引用,直接判定相等 if (identical(this, other)) return true; // 检查other是否为Item类型,且id、name完全匹配 return other is Item && runtimeType == other.runtimeType && id == other.id && name == other.name; } @override int get hashCode => Object.hash(id, name); }
更简洁的方式:使用Equatable包
如果你不想手动编写重复的相等性判断代码,可以借助equatable包来简化逻辑,它会自动帮你处理==运算符和hashCode的生成:
- 先在
pubspec.yaml中添加依赖:
dependencies: equatable: ^2.0.5
- 修改
Item类继承自Equatable:
import 'package:equatable/equatable.dart'; class Item extends Equatable { final int id; final String name; const Item({required this.id, required this.name}); @override List<Object?> get props => [id, name]; }
验证效果
修改完成后,再运行你的代码:
final Set<Item> _set1 = { Item(id: 1, name: "carrot"), Item(id: 2,name: "apple"), Item(id: 3,name: "mango") }; final Set<Item> _set2 = { Item(id: 1, name: "carrot"), }; print(_set1.intersection(_set2));
就能得到你预期的输出:{Instance of 'Item'}了。
内容的提问来源于stack exchange,提问作者Saffron-codes
相关产品推荐
相关产品推荐

