Java弱散列映射-需要根据值而不是键的弱点删除条目

Java弱散列映射-需要根据值而不是键的弱点删除条目,java,hashmap,weakhashmap,Java,Hashmap,Weakhashmap,因此,JavaWeakHashMap允许创建一个映射,如果其键变弱,其条目将被删除。但是,当映射中的值变弱时,如何创建其条目被删除的映射?我之所以要使用映射,是因为它是一个全局哈希表,可以根据对象的ID跟踪对象 ID ---> Object Address Key ---> Value (其中,ID是一个文本字符串) 我希望在对象地址变弱时删除键值对,而不是指向它们的字符串。有人对此有什么想法吗?支持这样的地图,例如: mapm=newmapmaker().weakValues

因此,Java
WeakHashMap
允许创建一个映射,如果其键变弱,其条目将被删除。但是,当映射中的值变弱时,如何创建其条目被删除的映射?我之所以要使用映射,是因为它是一个全局哈希表,可以根据对象的ID跟踪对象

ID --->  Object Address

Key ---> Value
(其中,
ID
是一个文本字符串)


我希望在对象地址变弱时删除键值对,而不是指向它们的字符串。有人对此有什么想法吗?

支持这样的地图,例如:

mapm=newmapmaker().weakValues().makeMap();
答案如下:

实现说明:WeakHashMap中的值对象由普通强引用持有。因此,应注意确保值对象不会直接或间接地强烈引用它们自己的键,因为这将防止键被丢弃。请注意,值对象可以通过WeakHashMap本身间接引用其键;也就是说,值对象可以强引用某个其他键对象,其关联的值对象反过来强引用第一个值对象的键。处理此问题的一种方法是在插入前将值本身包装在WeakReference中,如:
m.put(key,new WeakReference(value))
,然后在每次获取时展开

为什么要对条目进行垃圾收集?我认为有两个原因

  • 避免内存泄漏(避免让弱引用指向地图中的任何内容)
  • 如果对象被垃圾收集,那么myMap.get(myKey)应该返回null
  • 解决方案使用常规哈希映射:

    Map<String, WeakReference<Object>>
    
    Map
    
    如果2)是唯一的问题,那么只需使用myMap.get(myKey.get())


    如果您还需要删除条目,请查看描述softHashMap的条目,并对其进行调整以使用weakReferences…

    您可以执行WeakHashMap所做的操作,但要使用值而不是键:将您的值包装在weakReferences中,并将其与映射中的引用队列相关联。每当访问映射时,检查ReferenceQueue以查看是否添加了任何内容,如果添加了,则从映射中删除其条目。您需要创建一个子类WeakReference来保存密钥,以便知道要删除哪个条目。您还需要向查询映射的方法(get和containsKey、迭代器方法等)添加检查,以检查检索到的WeakReference是否确实包含值(请记住禁止空值,或者使用特殊的sentinel对象来表示它们)。

    您可能会发现这是一个有趣的阅读:感谢链接,卢卡斯——这是一个关于主体的伟大讨论,但它并不是问题的答案。如果在weakHashMap中插入WeakReference作为值,则如果引用的对象被垃圾回收,则不会发生任何事情(条目不会从映射中删除)…@pgras:当值仅从映射中引用(通过弱引用)时,可以回收。此时键(如果从值引用)也可以被回收。@subsubsub:it-键-如果弱可及(或软或虚)则可以回收但是,如果要将该键用作键,则该键必须是强可访问的…@pgras:不,您不需要强可访问键,hashmaps通过哈希进行搜索。仅检查该键以确保相等。如果该键已消失,那么就不会有相等性。@subsubsub:我同意您不需要强可访问键,但如果您的键不是强可访问键,则eachable,条目将从映射中删除(即使该值是强可访问的).现在我看到了一个解决方案,其中对键的唯一强引用来自于将自身包装在WeakRef中的值。但这里我们讨论的是使用字符串作为键,并且通过interning,让一个没有强引用的字符串在以后能够重新创建相等的字符串并不容易。这不起作用,不是吗将只在weakReferences中包装值,但在垃圾收集值时不会删除条目…@pgras:不,它也会删除条目。唯一的区别是,
    WeakHashMap
    在后续访问映射时删除过时的条目,而Guava的实现在后台线程中删除它们().您是对的,从文档“垃圾收集器回收其密钥或值的条目立即从映射中消失”非常感谢,这似乎是我见过的最好的解决方案。不幸的是,它需要向构建中添加如此大的JAR文件,但API似乎很棒。
    Map<String, WeakReference<Object>>