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

Flutter中如何深度比较包含嵌套类的两个List<Object>?

解决Flutter中嵌套类List的深度对比问题

1. 所有自定义类必须正确重写==运算符和hashCode

仅重写Address类不足以实现深度对比,User、Phone类也需要完成重写,且要处理嵌套列表的对比逻辑:

Phone类实现

class Phone {
  String number1;
  String number2;
  String number3;

  Phone({required this.number1, required this.number2, required this.number3});

  @override
  bool operator ==(Object other) {
    if (identical(this, other)) return true;

    return other is Phone &&
        other.number1 == number1 &&
        other.number2 == number2 &&
        other.number3 == number3;
  }

  @override
  int get hashCode => Object.hash(number1, number2, number3);
}

Address类实现(处理嵌套列表对比)

借助Flutter foundation包的listEquals来对比内部的列表字段:

import 'package:flutter/foundation.dart';

class Address {
  List<dynamic> housepos;
  List<dynamic> apartment;

  Address({required this.housepos, required this.apartment});

  @override
  bool operator ==(Object other) {
    if (identical(this, other)) return true;

    return other is Address &&
        listEquals(other.housepos, housepos) &&
        listEquals(other.apartment, apartment);
  }

  @override
  int get hashCode => Object.hash(housepos, apartment);
}

User类实现(处理嵌套的List
和List)

class User {
  List<Address> address;
  int age;
  String email;
  List<Phone> phone;

  User({required this.address, required this.age, required this.email, required this.phone});

  @override
  bool operator ==(Object other) {
    if (identical(this, other)) return true;

    return other is User &&
        listEquals(other.address, address) &&
        other.age == age &&
        other.email == email &&
        listEquals(other.phone, phone);
  }

  @override
  int get hashCode => Object.hash(address, age, email, phone);
}

2. 必须创建深拷贝的oldlistuser

如果仅用List.from(listuser)或listuser.toList()做浅拷贝,内部的User对象还是同一个引用,修改后对比会完全失效。需要给每个类添加深拷贝方法:

给Phone类添加拷贝方法

Phone copyWith({
  String? number1,
  String? number2,
  String? number3,
}) {
  return Phone(
    number1: number1 ?? this.number1,
    number2: number2 ?? this.number2,
    number3: number3 ?? this.number3,
  );
}

给Address类添加拷贝方法

Address copyWith({
  List<dynamic>? housepos,
  List<dynamic>? apartment,
}) {
  return Address(
    housepos: housepos ?? List.from(this.housepos),
    apartment: apartment ?? List.from(this.apartment),
  );
}

给User类添加拷贝方法

User copyWith({
  List<Address>? address,
  int? age,
  String? email,
  List<Phone>? phone,
}) {
  return User(
    address: address ?? this.address.map((a) => a.copyWith()).toList(),
    age: age ?? this.age,
    email: email ?? this.email,
    phone: phone ?? this.phone.map((p) => p.copyWith()).toList(),
  );
}

创建深拷贝的oldlistuser

// 加载完listuser后,生成深拷贝副本
List<User> oldlistuser = listuser.map((user) => user.copyWith()).toList();

3. 正确对比两个List

完成上述步骤后,可直接用Flutter的listEquals对比:

import 'package:flutter/foundation.dart';

bool hasChanges = !listEquals(oldlistuser, listuser);

或者继续使用DeepCollectionEquality,此时它会递归对比所有嵌套字段:

import 'package:collection/collection.dart';

bool hasChanges = !DeepCollectionEquality().equals(oldlistuser, listuser);

内容的提问来源于stack exchange,提问作者Андрей Ковынёв

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 15:42:42