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

如何获取两个Model列表的差异?toSet()方法处理Model无效

解决Dart中自定义Model列表的差异计算问题

你有两个AbsentModel类型的列表:

List<AbsentModel> a = [
  AbsentModel(name: "abir", id: 1),
  AbsentModel(name: "fahim", id: 2),
  AbsentModel(name: "rahim", id: 3),
  AbsentModel(name: "akash", id: 4),
];

List<AbsentModel> b = [
  AbsentModel(name: "akash", id: 4),
  AbsentModel(name: "fahim", id: 2),
  AbsentModel(name: "rahim", id: 3),
];

需要得到列表a中不在列表b里的元素,即:

List<AbsentModel> c = [AbsentModel(name: "abir", id: 1)];

直接用toSet()无效,是因为Dart中自定义类默认的==运算符比较的是对象引用,而非内容——即使两个AbsentModel的id和name完全一致,它们也是不同的对象,所以toSet()无法识别为重复项。

方法一:重写Model的==运算符和hashCode

如果需要基于name和id判断两个AbsentModel是否相等,直接在类中重写这两个方法:

class AbsentModel {
  final String name;
  final int id;

  AbsentModel({required this.name, required this.id});

  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is AbsentModel &&
          runtimeType == other.runtimeType &&
          name == other.name &&
          id == other.id;

  @override
  int get hashCode => name.hashCode ^ id.hashCode;
}

之后就可以用where结合toSet()来筛选差异:

List<AbsentModel> c = a.where((item) => !b.toSet().contains(item)).toList();

方法二:通过唯一标识(如id)筛选(无需修改Model)

如果id是AbsentModel的唯一标识,不需要修改Model类,直接提取b的id集合来对比:

// 先把列表b的所有id存入Set,提升查询效率
Set<int> bIds = b.map((model) => model.id).toSet();
// 筛选a中id不在bIds里的元素
List<AbsentModel> c = a.where((model) => !bIds.contains(model.id)).toList();

这种方法效率更高,尤其是当列表元素较多时,因为Set的contains操作时间复杂度是O(1),而直接用b.contains(item)是O(n)。

内容的提问来源于stack exchange,提问作者Kamal Hossain

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 04:52:35