当前位置:首页>鸿蒙APP>【鸿蒙】项目开发里面遇到的HashMap|Map找不到数据问题

【鸿蒙】项目开发里面遇到的HashMap|Map找不到数据问题

  • 2026-10-11 06:29:17
【鸿蒙】项目开发里面遇到的HashMap|Map找不到数据问题

在项目开发过程中遇到很奇怪的事情,使用HashMap的时候,可以存入的数据,但是在其他地方查询或者获取数据的时候一直找不到,通过Debug排查也是发现数据存在,但是拿不到...

但是通过自己循环遍历是能拿到的

 private getItemValueFromMap(bookId: string): NovelReaderSpeedRecord | undefined {    let record: NovelReaderSpeedRecord | undefined    this.records.forEach((value: NovelReaderSpeedRecord, key: string) => {      if (key == bookId) {        record = value        return      }    })    // record = this.records.get(bookId)    return record  }

所以问题可能就在HashMap|Map判断字符的逻辑上了,这跟Android里面的HashMap不太一样啊,那这不就是系统的bug吗?所以继续研究看看。

你用的“看起来一样”的字符串,其实不是“同一个字符串值”

在 ArkTS 的 Map 中,string 的比较比你想象的要「严格」。

❌ 场景 1:key 不是「原始 string」,而是 String 对象

key 不是「原始 string」,而是 String 对象

const map = new Map<string, string>();const key1 = 'params';const key2 = new String('params') as unknown as string;map.set(key1, 'value');map.get(key2); // ❌ undefined(鸿蒙里常见)

原因

Map 使用SameValueZero

String 对象 ≠ primitive string

ArkTS 对这点比浏览器更“严格暴露”,Map 判断 key 是否相等,用的是「SameValueZero」

primitive string 和 String 对象,永远不相等

ArkTS 中这个差异比浏览器更容易暴露出来

你看到的“看起来一样”的 key,其实是什么?

'params'new String('params')

打印出来都是:params

但实际上:

表达式
类型
本质
'params'string
原始值(primitive)
new String('params')object
包装对象

在 TS / JS 中验证一下

const a = 'params';const b = new String('params');console.log(typeof a); // stringconsole.log(typeof b); // objectconsole.log(a === b); // false
"==="比较时不会做拆箱(unboxing)

Map 底层是如何比较 key 的?(规范层)

Map 使用的是:SameValueZero

比较方式
结果
'a' vs 'a'
✅
NaN vs NaN
✅
0 vs -0
✅
'a'vs new String('a')
❌
obj1 vs obj2
❌(除非同引用)

SameValueZero不会把 object 自动转 primitive

为什么 ArkTS 更容易踩到这个坑?

原因不是 Map,而是 字符串来源
在浏览器里你很少手写 new String()
但在 ArkTS 中:
常见「隐式 String 对象」来源
  1. Native / C++ 透传
  2. 系统参数(want / ability)
  3. JSON → ArkRuntime
  4. 框架层做了一层包装
const key = want.parameters['params']; 

你以为是 string,但底层可能是:

String { "params" }

为什么 set 能成功,但 get 却失败?

map.set(primitive_string, 'value');map.get(String_object); // 查不到

因为set的时候已经做了转化

解决方案(必须)

key 统一 primitive 化

const safeKey = String(key2);map.get(safeKey);

鸿蒙 ArkTS 中最稳妥的写法(推荐你直接用)

function normalizeKey(key: unknown): string { return String(key).trim();}

完整例子:

export class  MyHashMap<V> extends HashMap<string,V>{  override hasKey(key: string): boolean {    return super.hasKey(this.normalizeKey(key));  }  override get(key: string): V {    return super.get(this.normalizeKey(key));  }  override set(key: string, value: V): Object {    return super.set(this.normalizeKey(key), value);  }  override remove(key: string): V {    return super.remove(this.normalizeKey(key));  }  private normalizeKey(key: string): string {    return String(key).trim();  }}

其他建议:https://z.l6j.cn/Y5EgkB

在ArkTS 3.x ~ 4.x:

Map对 key 来源非常敏感

JSON / Native / System 参数 一定要 normalize

官方 demo 里也几乎都用 Record

const params: Record<string, string> = {};params[key] = value;params[key]; // 永远 OK

最新文章

随机文章