美文网首页
Dart重写==的同时,还需要重写hashCode

Dart重写==的同时,还需要重写hashCode

作者: 浩然爸 | 来源:发表于2024-03-03 14:25 被阅读0次

在进行dart编码,通过Android Studio快捷键进行重写==时,会同时让你重写hashCode,很多人会疑惑为什么要重写hashCode,因为我只要重写了==,就可以正确的进行判断,因此认为不需要重写hashCode。

main(List<String> args) {
  Person p1 = Person('aa');
  Person p2 = Person('aa');
  print(p1 == p2);
}

class Person {
  final String name;
  Person(this.name);
  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is Person && runtimeType == other.runtimeType && name == other.name;
}

运行结果为:true

通过运行结果来看,确实可以判断两个对象是否相等,然而这个相等却不是真正意义上的相等,当我们使用Set时,便会发现问题。

Set set = Set();
  set.add(p1);
  set.add(p2);
  print(set);

运行结果:{Instance of 'Person', Instance of 'Person'}

此时set中存储了两个Person对象,按照我们的期望,此时set中应该只有一个Person对象才对,问题就在hashCode。

Set set = Set();
  set.add(p1);
  set.add(p2);
  print(p1.hashCode);
  print(p2.hashCode);
  print(set);

结果:
p1.hashCode = 1052511799
p2.hashCode = 307180047
{Instance of 'Person', Instance of 'Person'}

通过打印结果可以看出,两个Person对象的hashCode是不相等的,set在插入数据时,除了进行==判断外,还会对比hashCode是否相同。因此,set认为,他们是两个不同的对象,要解决这个问题,就需要重写hashCode。

main(List<String> args) {
  Person p1 = Person('aa');
  Person p2 = Person('aa');
  print(p1 == p2);

  Set set = Set();
  set.add(p1);
  set.add(p2);
  print('p1.hashCode = ${p1.hashCode}');
  print('p2.hashCode = ${p2.hashCode}');
  print(set);
}

class Person {
  final String name;
  Person(this.name);
  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is Person && runtimeType == other.runtimeType && name == other.name;

  @override
  int get hashCode => name.hashCode;
}

结果:
p1.hashCode = 813790094
p2.hashCode = 813790094
{Instance of 'Person'}

此时,便得到了我们期望的结果。

但是,如果对象中包含List/Map需要如何处理?List/Map的Equal判断可以使用系统的listEquals(a, b)/mapEquals(a, b)方法。但是hashCode没有找到对应的方法,因此,我们需要自己写一个

class Person {
  final String name;
  Person(this.name);
  List list = [];
  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is Person &&
          runtimeType == other.runtimeType &&
          name == other.name &&
          listEquals(list, other.list);

  @override
  int get hashCode => name.hashCode ^ listHashCode(list);
}

int listHashCode(List<dynamic> list) {
  int hashCode = 0;
  list.forEach((element) {
    hashCode = hashCode ^ element.hashCode;
  });
  return hashCode;
}

main(List<String> args) {
  Person p1 = Person('aa');
  p1.list.add('a');
  Person p2 = Person('aa');
  p2.list.add('a');

  Set set = Set();
  set.add(p1);
  set.add(p2);
  print('p1.hashCode = ${p1.hashCode}');
  print('p2.hashCode = ${p2.hashCode}');
  print(set);
}

结果:
p1.hashCode = 984606668
p2.hashCode = 984606668
{Instance of 'Person'}

所以,重写==时,必须要重写hashCode,从而实现真正的相等。

相关文章

  • 第三章所有对象的通用方法

    目录 重写equals方法时遵守通用约定 重写equals方法时同时也要重写hashcode方法 始终重写 toS...

  • hashCode equals

    HashMap 使用对象做key 的时候,必须重写equals(),同时必须重写hashCode() 因为Hash...

  • hashcode

    JAVA中重写equals()方法的同时要重写hashcode()方法 object对象中的 public boo...

  • hashCode 与 equals

    “你重写过 hashcode 和 equals 么,为什么重写equals时必须重写hashCode方法?” ha...

  • 为什么重写equals一定要重写hashcode?

    两篇文章搞懂为什么重写equals一定要重写hashcode? 为什么重写equals一定要重写hashcode?...

  • java基础--集合和流

    1.Map()重写equal同时重写hashCode()方法 Object类中的equal()和==是相同的 S...

  • Collection集合

    hashcode() 和 equals() 方法最好都同时重写 equals相等,hashcode一定相等 has...

  • 第五章

    #1 【强制】关于hashCode和equals的处理,遵循如下规则# 1.重写equals,即必须重写hashCode

  • 为什么重写equal()要重写hashcode()

    为什么重写equals()要重写hashcode() 答:hashcode判断是equals判断的先决条件;所以对...

  • Effective Java 案例分享(三)

    11、重写Object.equals时,必须重写Object.hashcode 如果需要重写Object的equa...

网友评论

      本文标题:Dart重写==的同时,还需要重写hashCode

      本文链接:https://www.haomeiwen.com/subject/xopkzdtx.html