当前位置:网站首页>Do you really understand the logic that two objects are equal in dart?

Do you really understand the logic that two objects are equal in dart?

2022-06-09 06:45:00 Ma Nong on the island

Poke here to learn 《Flutter Introduction and actual combat 》 special column , Continuous updating 、 System learning !

Preface

Generally speaking, we will not implement the custom equality judgment of classes , Any object built at this time has different values or hash code Different , Use == When judging, they always return false Of . And on some occasions , If we want to use it directly == To determine whether the custom classes are equal , It needs to be covered at the same time == Operators, and hashCode Method . When using custom object equality implementation , What should we pay attention to in coding , This article is to summarize the relevant contents for you .

Judgment of equality of objects

Let's see first Java A classic interview question in language , That is, what is the output result of the console in the following code .

Integer a=127;
Integer b=127;
System.out.println(a==b);

Integer c=128;
Integer d=128;
System.out.println(c==d);

As a result, the first print is true, The second print is false. This is because Java Medium -128 to 127 The integer object of the range uses a cache , Outside this scope are newly built objects . that Dart in , What is a similar situation ?


  int a = 127;
  int b = 127;
  print(a == b);

  int c = 128;
  int d = 128;
  print(c == d);

The results are all true, This is because Dart Operator overloading is supported , Two objects are actually equal == Operators, and hash code Judgmental .int and double All inherit from numeric classes num. For this type ,hash code Is the value itself , and == The operator actually uses compareTo Method to judge , So as long as the values of two numeric classes are equal ( Except for special values , such as double.nan,double.infinity), So use == When the comparator operates, it is equal .

The same is true for string types , As long as the character sequence of the string is consistent , that hash code It is also consistent . however , about unicode for , If different codes are used , that hash code It's not equal . therefore , stay Dart in , Comparing string equality does not require the use of similar Java Of equals Method , Use it directly == Operator is OK .

This actually gives us another kind of flexibility , For example, when we want two objects of the same type to be equal , You can override == Operators, and hashCode Method , To achieve some of our purposes . for example Widget Do you want to refresh , Another example is that we are Redux Talked about , Because every time Redux All return a new one State object , If you want to reduce the refresh when the actual data does not change , Then you can do the same . For details, please refer to :Redux Utilization of distinct Property to optimize performance .

With the above knowledge , Let's look at the precautions when judging the equality of custom objects .

If it covers == Operator's words , Be sure to cover both hashCode Method

default hashCode Method will produce a unique hash value —— This means that under normal circumstances , When only two objects are unified , Their two hash values will be equal . When we want to cover == When the operator , It means that we have other definitions for judging the equality of objects of this class . The principle of equal objects must satisfy that both have the same hash value at the same time . therefore , If you don't cover hashCode Method , It means it will fail on some occasions , such as Map And other sets based on hash value judgment , Even if the elements in two sets meet the equality condition , But because the hash values of equal elements are different , As a result, the two sets cannot satisfy the equality judgment .

== Operators should satisfy the mathematical equality rule

The math , Equality needs to satisfy three rules :

  • Reflexivity : namely a == a Should always return true.
  • symmetry : if a == b that b == a It should also be for true.
  • Transitivity : if a == b And b == c, that a == c It should also be for true.

It means our hashCode Method or == Operator methods cannot filter the equality judgment of some attributes of objects based on conditions . For example, the skip object attribute is null The situation of , It may lead to the invalidation of one of the three rules given to you .

For variable classes , Custom equality judgments should be avoided

What is a mutable class ? Is the class whose properties of the object may change during operation . because , Consider the above mathematical equality rule , Then, when generating hash values for custom equality , All properties of the object should be taken into account . And if these properties will be changed during operation , That means that the hash value of this object will change . This actually violates the principle of reflexivity ( Same object , The hash values before and after are not equal , It's like you can't recognize your girlfriend after she changes her hairstyle , Is to be beaten ), For collections based on hash values , It's impossible to predict this change , This will lead to an error in the equality judgment of the set .

Don't put == The parameters of the operator apply to nullable objects

stay Dart in ,null Will only be equal to itself , Therefore, only when the object to be compared is not empty should == Operator for equality judgment .

//  The correct sample 
class Person {
    
  final String name;
  // ···

  bool operator ==(Object other) => other is Person && name == other.name;
}

// The wrong sample 
class Person {
    
  final String name;
  // ···

  bool operator ==(Object? other) =>
      other != null && other is Person && name == other.name;
}

Be careful : stay Dart Introduction null safety Version before , The object is allowed to be null Of . Even so ,Dart I can't use null Call custom Method to judge equality ( It can be understood as Dart Direct processing as false 了 ). therefore , In Africa null safety edition (< 2.12 edition ), We don't need to be in In method processing null.

summary

This article introduces Dart Mechanism of object equality in , And the precautions for judging the equality of user-defined class objects . In most cases , We don't need to override the object equality judgment ourselves , But when you need it on some occasions , Please follow these suggestions , To avoid inexplicable problems .

原网站

版权声明
本文为[Ma Nong on the island]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/160/202206090639314572.html