dart-lang / collection

The collection package for Dart contains a number of separate libraries with utility functions and classes that makes working with collections easier.

Home Page:https://pub.dev/packages/collection

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Issue with comparing custom lists and items on 1.14.11

firatcetiner opened this issue · comments

Issue

This plugin isn't working when dealing with custom lists/items. For example, I have an UserModel class and list of users. I want to compare two lists to find the equality between. I've tried ListEquality, DeepListEquality and unordered versions of these two. I can't test it on 1.14.12 because I'm on the stable channel.

Am I doing something wrong?

Example Demo

Gist Demo

The UserModel:

class UserModel {

  int userId;
  String name;
  String nickName;
  String email;
  
  UserModel({
    @required this.userId,
    @required this.name,
    @required this.nickName,
    @required this.email
  });

}

I will switch to the beta channel and test it with the latest version, assuming it won't give "flutter_test from sdk is forbidden" error.

flutter doctor -v

[√] Flutter (Channel stable, v1.12.13+hotfix.7, on Microsoft Windows [Version 10.0.18362.657], locale tr-TR)
    • Flutter version 1.12.13+hotfix.7 at C:\Users\asus\Documents\SDK\flutter
    • Framework revision 9f5ff2306b (3 weeks ago), 2020-01-26 22:38:26 -0800
    • Engine revision a67792536c
    • Dart version 2.7.0

 
[√] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
    • Android SDK at C:\Users\asus\AppData\Local\Android\sdk
    • Android NDK location not configured (optional; useful for native profiling support)
    • Platform android-29, build-tools 29.0.2
    • Java binary at: C:\Program Files\Android\Android Studio\jre\bin\java
    • Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b03)
    • All Android licenses accepted.

[√] Android Studio (version 3.5)
    • Android Studio at C:\Program Files\Android\Android Studio
    • Flutter plugin version 43.0.1
    • Dart plugin version 191.8593
    • Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b03)

[√] VS Code (version 1.42.1)
    • VS Code at C:\Users\asus\AppData\Local\Programs\Microsoft VS Code
    • Flutter extension version 3.8.1

[√] Connected device (1 available)
    • MI 6 • 16185061 • android-arm64 • Android 9 (API 28)

• No issues found!

You don't show the definition of UserModel in your example, does it have a definition for operator ==?

The DeepEquality are deep in terms of collections, not objects. We still use normal equality checks for objects. If you aren't defining your own operator == that means that two separate UserModel variables will only compare equally if they are the same instance.

class NoCustomEquals {
  final int id;
  NoCustomEquals(this.id);
}

class CustomEquals {
  final int id;
  CustomEquals(this.id);

  @override
  int get hashCode => id;

  @override
  bool operator ==(Object other) =>
    other is CustomEquals && other.id == id;
}

[1, 2] == [1, 2]; // false, instance equality by default.
DeepCollectionEquality([1, 2], [1, 2]); // true, compares elements and 1==1, 2==2
NoCustomEquality(1) == NoCustomEquality(1); // false, instance equality
CustomEquality(1) == CustomEquality(1); // true, different instances compare equal

DeepCollectionEquality(
  [NoCustomEquality(1), NoCustomEquality(2)],
  [NoCustomEquality(1), NoCustomEquality(2)],
); // false - because the two instances are not the same.

DeepCollectionEquality(
  [CustomEquality(1), CustomEquality(2)],
  [CustomEquality(1), CustomEquality(2)],
); // true

var a = NoCustomEquality(1);
var b = NoCustomEquality(2);

DeepCollectionEquality([a,b], [a,b]); // true - same instances

Closing for now, if you do define a working operator == and still having trouble, please reply with a full reproduction.

You don't show the definition of UserModel in your example, does it have a definition for operator ==?

The DeepEquality are deep in terms of collections, not objects. We still use normal equality checks for objects. If you aren't defining your own operator == that means that two separate UserModel variables will only compare equally if they are the same instance.

class NoCustomEquals {
  final int id;
  NoCustomEquals(this.id);
}

class CustomEquals {
  final int id;
  CustomEquals(this.id);

  @override
  int get hashCode => id;

  @override
  bool operator ==(Object other) =>
    other is CustomEquals && other.id == id;
}

[1, 2] == [1, 2]; // false, instance equality by default.
DeepCollectionEquality([1, 2], [1, 2]); // true, compares elements and 1==1, 2==2
NoCustomEquality(1) == NoCustomEquality(1); // false, instance equality
CustomEquality(1) == CustomEquality(1); // true, different instances compare equal

DeepCollectionEquality(
  [NoCustomEquality(1), NoCustomEquality(2)],
  [NoCustomEquality(1), NoCustomEquality(2)],
); // false - because the two instances are not the same.

DeepCollectionEquality(
  [CustomEquality(1), CustomEquality(2)],
  [CustomEquality(1), CustomEquality(2)],
); // true

var a = NoCustomEquality(1);
var b = NoCustomEquality(2);

DeepCollectionEquality([a,b], [a,b]); // true - same instances

Closing for now, if you do define a working operator == and still having trouble, please reply with a full reproduction.

Thanks! I guess it is not necessary to use this package for me to simply compare two "custom lists" for equality, since I'm overriding both hashCode and operator ==, just using == would be enough. Am I correct?

Yes, if you have an implementation of List that defines hashCode and operator == to be dependent on their elements you probably don't need to use the CollectionEquality classes.