Dart使用indexOf()无法在自定义对象列表中查找对应元素索引问题求解
问题原因
Dart内置的Object类默认的==运算符仅判断两个对象是否为同一个内存引用实例,不会比对属性值是否相等。而List.indexOf()方法内部依赖==运算符匹配元素,因此哪怕两个实例的所有属性值完全一致,只要不是同一个对象,就会被判定为不匹配,返回-1。
你遇到的list.indexOf(list[0])也返回-1的情况,大概率是存入列表的元素和读取时的元素不是同一个引用实例,比如经过了序列化/反序列化、深拷贝操作,重写相等判断逻辑后即可解决。
解决方案
方案1:重写类的相等判断逻辑(推荐,适合频繁需要比对的场景)
在你的Standard类中添加==运算符和hashCode的重写逻辑即可。浮点类型建议通过判断差值绝对值小于极小值的方式比对,避免浮点精度误差导致的判断异常:
@override bool operator ==(Object other) => identical(this, other) || other is Standard && runtimeType == other.runtimeType && // 浮点类型判断差值小于极小值避免精度问题 (l - other.l).abs() < 1e-9 && (a - other.a).abs() < 1e-9 && (b - other.b).abs() < 1e-9 && (lUpperTolerance - other.lUpperTolerance).abs() < 1e-9 && (lLowerTolerance - other.lLowerTolerance).abs() < 1e-9 && (aUpperTolerance - other.aUpperTolerance).abs() < 1e-9 && (aLowerTolerance - other.aLowerTolerance).abs() < 1e-9 && (bUpperTolerance - other.bUpperTolerance).abs() < 1e-9 && (bLowerTolerance - other.bLowerTolerance).abs() < 1e-9 && (eTolerance - other.eTolerance).abs() < 1e-9 && timestamp == other.timestamp && identStr == other.identStr; @override int get hashCode => Object.hash( l, a, b, lUpperTolerance, lLowerTolerance, aUpperTolerance, aLowerTolerance, bUpperTolerance, bLowerTolerance, eTolerance, timestamp, identStr, );
重写后再调用indexOf()就会按照属性值匹配目标对象。
方案2:使用indexWhere手动比对(适合临时单次查询场景)
如果不想修改类定义,可以直接调用列表的indexWhere方法自定义比对规则:
int targetIndex = list.indexWhere((item) { return (item.l - target.l).abs() < 1e-9 && (item.a - target.a).abs() < 1e-9 && (item.b - target.b).abs() < 1e-9 && // 其余属性比对规则和上面一致,按需补充即可 item.timestamp == target.timestamp && item.identStr == target.identStr; });
内容的提问来源于stack exchange,提问作者Vincent Guttmann
相关产品推荐
相关产品推荐

