首页 > 解决方案 > 使用列表因为 Map 的键总是返回 null

问题描述

为了解决一个问题,我预先填充了一个地图,然后在需要时尝试从地图中提取答案。

地图填充如下:

var cycles = {
  [0, 0, 0, 0, 0, 0, 0, 0] : [[0, 1, 1, 1, 1, 1, 1, 0], [0, 0, 1, 1, 1, 1, 0, 0], [0, 0, 0, 1, 1, 0, 0, 0], [0, 1, 0, 0, 0, 0, 1, 0], [0, 1, 0, 1, 1, 0, 1, 0], [0, 1, 1, 0, 0, 1, 1, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 1, 1, 1, 1, 1, 1, 0], [0, 0, 1, 1, 1, 1, 0, 0], [0, 0, 0, 1, 1, 0, 0, 0], [0, 1, 0, 0, 0, 0, 1, 0], [0, 1, 0, 1, 1, 0, 1, 0], [0, 1, 1, 0, 0, 1, 1, 0], [0, 0, 0, 0, 0, 0, 0, 0]],
  [0, 0, 0, 0, 0, 0, 0, 1] : [[0, 1, 1, 1, 1, 1, 0, 0], [0, 0, 1, 1, 1, 0, 0, 0], [0, 0, 0, 1, 0, 0, 1, 0], [0, 1, 0, 1, 0, 0, 1, 0], [0, 1, 1, 1, 0, 0, 1, 0], [0, 0, 1, 0, 0, 0, 1, 0], [0, 0, 1, 0, 1, 0, 1, 0], [0, 0, 1, 1, 1, 1, 1, 0], [0, 0, 0, 1, 1, 1, 0, 0], [0, 1, 0, 0, 1, 0, 0, 0], [0, 1, 0, 0, 1, 0, 1, 0], [0, 1, 0, 0, 1, 1, 1, 0], [0, 1, 0, 0, 0, 1, 0, 0], [0, 1, 0, 1, 0, 1, 0, 0]],
  ...
};

后来,一个函数被这样调用:

print(pullAnswerFromMap([1,0,0,1,0,0,1,0], 1000000000));

其中pullAnswerFromMap函数定义为:

return cycles[cells][N % 14 == 0 ? 14 : N % 14];

cycles映射将包含所有可能的密钥 - 所有 256 个 8 位列表。

但是当运行带有示例的代码进行测试时,我得到以下信息:

Unhandled exception:
NoSuchMethodError: The method '[]' was called on null.
Receiver: null

所以,在 return 语句之前,我添加了print(cycles);- 地图打印得很好。所有数据都在那里。然后我添加了print(cycles[[1,0,0,1,0,0,1,0]]);which prints null,即使我可以在上一个 print 语句的输出中看到它存在于地图中。

因此,似乎密钥不是基于列表的相等性,而是基于列表的特定实例(内存地址?)。尝试从映射中检索值时,具有相同顺序的相同元素的新列表将返回 null。

我的问题是:我该如何解决这个问题,这样它就cycles[[1,0,0,1,0,0,1,0]]不会返回null,而是返回List<List<int>>与之关联的那个?

标签: dart

解决方案


因此,似乎密钥不是基于列表的相等性,而是基于列表的特定实例(内存地址?)。

Map(默认为 a LinkedHashMap)使用键类型的operator ==andhashCode来确定两个键是否相同。 List不会覆盖那些;两个单独的List实例永远不会比较相等,因此您从键中查找Map值的尝试List总是会失败。

解决这个问题的几种方法是:

  • 显式使用构造函数LinkedHashMap以便您可以提供自己的回调来计算哈希码并确定两个键是否相等。

  • 为键创建一个自定义类Map,您的类在其中有一个List<int>成员operator ==hashCode适当地覆盖。

请参阅如何比较 Dart 中的列表是否相等?了解如何对Lists 进行深度相等检查。


推荐阅读