How to solve: I don't get why my equality operator implementation dosen't work here and returns true

Question

Asked by Be h on December 31, 2021 (source).

class SomeObject {
    final List list;
    final int integer;
    SomeObject({required this.integer, required this.list});
    @override
    bool operator == (Object other) {
        if (other is SomeObject && integer == other.integer) {
            if (other.list.length != list.length) {
                return false;
            }
            for (int i = 0; i < list.length; i++) {
                if (list[i] == other.list[i]) {
                    return true;
                }
            }
            return false;
        }
        return false; 
    }
     
    @override
    // TODO: implement hashCode
    int get hashCode => Object.hashAll(list);
}


void main(){
    var b = SomeObject(integer: 4, list: [5, 6, 7]);
    var c = SomeObject(integer: 4, list: [5, 6, 8]);
    print(b == c);
    // Here equality operator returns true while it should return false. 
    // I think there is some problem in comparing individual list elements.
}

Answer

Question answered by Juan C (source).

Consider using != and return false in this part:

for (int i = 0; i < list.length; i++) {
  if (list[i] == other.list[i]) {
    return true;
  }
}

If we look carefully why it is failing:

var b = SomeObject(integer: 4, list: [5, 6, 7]);
var c = SomeObject(integer: 4, list: [5, 6, 8]);

First loop: i = 0

if (list[0] == other.list[0]) { // 5 == 5
  return true; // it stops and immediately returns true 
}

If we use != and return false, it will break the loop as soon as the elements at index i are not equal.

for (int i = 0; i < list.length; i++) {
  if (list[i] != other.list[i]) {
    return false;
  }
}

Last loop: i = 2

if (list[2] != other.list[2]) { // 7 == 8 
  return false; 
}

But if you want a shorter way to do this:

import 'package:flutter/foundation.dart';

class SomeObject {
  final List list;
  final int integer;

  SomeObject({
    required this.list,
    required this.integer,
  });


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

    return other is SomeObject &&
        listEquals(other.list, list) &&
        other.integer == integer;
  }

  @override
  int get hashCode => list.hashCode ^ integer.hashCode;
}

DART FLUTTER
SHARE: