You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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的生成:

  1. 先在pubspec.yaml中添加依赖:
dependencies:
  equatable: ^2.0.5
  1. 修改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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 01:17:47