Flutter/Dart在Map中使用类作为键。

huangapple go评论61阅读模式
英文:

Flutter/Dart using a class as a key in a Map

问题

I have a class:

class MyClass {
  MyClass(this.id, this.name);

  final int id;
  final String name;
}

The class is then added to a Map with some extra information:

Map<MyClass, String> myMap = { 
   MyClass(0, "Hello")  : "First", 
   MyClass(1, "World!") : "Second" 
};

I then have some callback function:

function doMagic(MyClass thisOne) {
  String? value = myMap[thisOne];
}

Now that should work fine, if you are using the same Object... But actually the thisOne is being recreated from a database and is therefore not the same Object as the one in myMap so there is no match.

The only way I can think of to do this is:

function doMagic(MyClass thisOne) {
  List<MyClass> matchItem = myMap.keys.where((my) => my.id == thisOne.id).toList();
  String? value;

  if(matchItem.isNotEmpty) {
    value = myMap[matchItem[0]];
  }
}

I've read somewhere about the issue with checking Maps for Objects because of this issue (it is looking for the instance which is equal rather than the contents). Is there an easier way?

英文:

I have a class:

class MyClass {
  MyClass(this.id, this.name);

  final int id;
  final String name;
}

The class is then added to a Map with some extra information:

Map&lt;MyClass, String&gt; myMap = { 
   MyClass(0, &quot;Hello&quot;)  : &quot;First&quot;, 
   MyClass(1, &quot;World!&quot;) : &quot;Second&quot; 
};

I then have some callback function:

function doMagic(MyClass thisOne) {
  String? value = myMap[thisOne];
}

Now that should work fine, if you are using the same Object... But actually the thisOne is being recreated from a database and is therefore not the same Object as the one in myMap so there is no match.

The only way I can think of to do this is:

function doMagic(MyClass thisOne) {
  List&lt;MyClass&gt; matchItem = myMap.keys.where((my) =&gt; my.id == thisOne.id).toList();
  String? value;

  if(matchItem.isNotEmpty) {
    value = myMap[matchItem[0]];
  }
}

I'm sure I've read somewhere about the issue with checking Maps for Objects because of this issue (it is looking for the instance which is equal rather than the contents). Is there an easier way?

答案1

得分: 1

感谢@Richard Heap...

答案是提供一个==操作符的重写和一个hashCode的重写,然后允许Map []操作符使用其中一个来进行值的相等性比较。

class MyClass {
  MyClass(this.id, this.name);

  final int id;
  final String name;

  bool operator==(Object other) =>
      other is MyClass && id == other.id && name == other.name;

  int get hashCode => Object.hash(id, name);
}

现在,这个代码能够正确运行:

function doMagic(MyClass thisOne) {
  String? value = myMap[thisOne];
}
英文:

Thanks goes to @Richard Heap...

The answer is to provide both an == operator override and a hashCode override, which then allows the Map [] operator to use one of those to do the value equality comparison.

class MyClass {
  MyClass(this.id, this.name);

  final int id;
  final String name;

  bool operator==(Object other) =&gt;
      other is MyClass &amp;&amp; id == other.id &amp;&amp; name == other.name;

  int get hashCode =&gt; Object.hash(id, name);
}

Now, this works correctly:

function doMagic(MyClass thisOne) {
  String? value = myMap[thisOne];
}

huangapple
  • 本文由 发表于 2023年5月18日 01:43:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/76274851.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定