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

Dart:如何正确比较包含自定义对象的无序列表?

解决Dart中无序列表包含属性相同对象的相等性比较问题

你说得没错,问题根源就是不同的对象实例——默认情况下Dart的自定义类(比如你的Article)会用引用地址来判断相等性,哪怕两个对象的id和name完全一样,只要是独立创建的不同实例,==运算符就会返回false。这也是为什么你把同一个实例放进两个列表时结果是true,而用两个属性相同的不同实例就不行,哪怕用了DeepCollectionEquality.unordered()也没用——因为它内部还是会调用每个元素的==来判断,而你的Article没重写这个方法。

要解决这个问题,咱们需要两步走:

1. 给Article类重写==运算符和hashCode

Dart规范里要求,如果你重写了==,必须同时重写hashCode,不然会导致集合(比如Set、HashMap)的行为异常。咱们根据id和name这两个关键属性来实现:

class Article {
  final String id;
  final String name;

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

  // 重写==运算符,比较id和name是否都相等
  @override
  bool operator ==(Object other) {
    if (identical(this, other)) return true;
    return other is Article && other.id == id && other.name == name;
  }

  // 重写hashCode,基于id和name生成唯一哈希值
  @override
  int get hashCode => Object.hash(id, name);
}

2. 使用无序深度集合比较

现在你的Article实例会根据属性判断相等了,接下来用DeepCollectionEquality.unordered()来比较两个无序列表就会返回正确结果了:

import 'package:collection/collection.dart';

void main() {
  var a = <Article>[];
  var b = <Article>[];
  var article1 = Article(id: "1", name: "Beer");
  var article2 = Article(id: "1", name: "Beer");
  a.add(article1);
  b.add(article2);
  
  // 现在会输出true
  print(DeepCollectionEquality.unordered().equals(a, b));
}

解释一下:DeepCollectionEquality.unordered()会忽略列表的元素顺序,只要两个列表包含的元素(按重写后的==判断)完全一致,就会返回true。如果你的列表是有序的,那用listEquals就可以了,但根据你的需求,无序的情况用这个方法更合适。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:31:59