带有多个密钥的Java WeakHashMap?

时间:2012-12-13 04:21:01

标签: java scala garbage-collection hashmap

我正在寻找与

相当的东西
WeakHashMap<K, V>

类,除了它将多个键映射到一个值,所以它更像是

WeakHashMap<K1, K2, V>
WeakHashMap<K1, K2, K3, V>
etc.

getset条目的方式就像数据库中的多列主键:您使用多个键放置项目,例如(K1, K2),要将该项目退回,您需要提供所有相同的密钥。相应的get&amp; set语义,GC语义将是:当一个条目不再可达时将被GC化,这意味着其任何的密钥不再可达。

还有其他人之前需要这样的东西吗?你会如何处理这样的要求?将一个元组存储为关键,就像在非弱HashMap中一样,它不起作用(元组几乎立即得到GC,没有人指向它)。

如果在我开心使用它之前已经做了类似的事情,而只是试着想一想如何用WeakReferences和普通的hashmap构建这样的东西,并且我想出一个空白。

1 个答案:

答案 0 :(得分:1)

有趣的问题。我不知道这个的任何实现,但我会通过调整WeakHashMap的源来实现它。它使用ReferenceQueue并在几乎所有公共方法的开头轮询它,删除每个gc'ed指示对象的条目。

以下是我如何使WeakHashMap成为多键弱映射的粗略概述:

  1. 定义与您描述的复合键,并将其用于主条目集
  2. 维护从关键组件到其参与的键组的内部映射
  3. 当您在ReferenceQueue上找到引用组件时,查找它所参与的键组并从主条目集中删除这些键
  4. 您还需要从其他每个关键组件的集合中删除它所参与的每个键。也就是说,假设您在引用队列中找到了一个关键组件c 1 ,并且它参与了键k 1 ,...,k n 。然后对于每个k i ,如果其他关键组件是c 2 和c 3 ,则需要删除k i 来自c 2 和c 3 的键集,以及删除c 1 的整个条目。
  5. 当组件的键集为空时,您可能还应该删除该组件的键集映射条目。这意味着您可能会在引用队列中找到组件到键集映射中没有相应数据的组件。
  6. 美中不足的是,所有这些内部地图必须以不会阻止关键组件被gc的方式设置。也就是说,在这个多键映射结构中必须没有硬(或软)引用。 WeakHashMap通过使其内部Entry类(实现Map.Entry)扩展WeakReference来实现此目的。当密钥是gc'ed时,放置在引用队列中的是Entry对象,而不是密钥本身。这样的东西必须用于所有内部结构的设计(复合键对象,条目集,从键组件到键组的映射,以及键组本身)。