IdentityHashMap和WeakHashMap的组合

11
我需要一个实现Map接口的类,它可以同时具备 IdentityHashMapWeakHashMap 的属性(使用引用相等性而不是 equals() 方法匹配键,并且使用引用弱化机制管理键)。
请问您推荐哪个实现类?(该类必须能在Android上运行)

1
@fge 我也是这样想的,但这不会在收集时从映射中删除键。 - assylias
无论如何,回到问题本身,你为什么需要那个呢? - fge
@fge 嗯,这很复杂:我正在实现类似于微软WPF的MVVM库,分部署在Android上。有一个叫做“DependencyProperty”的东西,该属性的值容器存储在“Map”中。当“DependencyProperty”所有者被收集时,它们必须从地图中删除... - zduny
1
map.get(new Wrapper(t)); 应该可以工作。 - assylias
5
给那些阅读这些评论的漫游程序员 - 不要使用fge的解决方案 - 它不起作用。它可能看起来像是可以工作的,但实际上它已经失效了。原因在于 - WeakHashMap 将会指向 Equivalence.Wrapper<K> 而不是 K,因此当 Equivalence.Wrapper<K> 被收集时,键将被删除,而非当 K 被收集时。Equivalence.Wrapper<K> 可能会(很可能)在 K 仍然存在时被收集。 - zduny
显示剩余10条评论
1个回答

6
如果您建议使用Guava,那么new MapMaker().weakKeys().makeMap()可以直接完成工作,因为 weakKeys 使用引用相等来比较键。 weakKeys 的文档说明如下:
指定存储在映射中的每个键(而不是值)都应该包装在一个WeakReference中(默认情况下使用强引用)。 警告:当使用此方法时,生成的映射将使用标识(==)比较确定键的相等性,这是地图规范的技术违规,并且可能不是您所期望的。

谢谢!那如果不用Guava呢? - LppEdd
根据我的第一条评论,在 IntelliJ 插件的范围内,我使用了两个 IdentityHashMap 和一个可释放的分层系统(由平台提供)来解决问题。https://github.com/lppedd/idea-conventional-commit/blob/14ae62bf034a07467f465d41e728a9b03a2cfe16/src/main/kotlin/com/github/lppedd/cc/completion/CommitCompletionContributor.kt?fbclid=IwAR0Sly65RaInSLZKXRUPHfp-irHfVAQfRvCq4GTW0SW1dZHjE6ytYjC2-do#L157-L170 - LppEdd
如果您不想使用Guava,那么plume-util库中的类WeakIdentityHashMap可以实现相同的功能。 - mernst

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接