4

Java 的弱哈希映射这样的弱哈希表使用弱引用来跟踪垃圾收集器对无法访问的键的集合,并从集合中删除与该键的绑定。弱哈希表通常用于实现从图中的一个顶点或边到另一个的间接寻址,因为它们允许垃圾收集器收集图的不可达部分。

这种数据结构是否存在纯粹的功能等价物?如果没有,如何创建一个?

这似乎是一个有趣的挑战。内部实现不可能是纯粹的,因为它必须收集(即变异)数据结构以删除无法访问的部分,但我相信它可以为用户提供一个纯粹的界面,用户永远无法观察到杂质,因为它们只影响数据的一部分根据定义,用户无法再访问的结构。

4

2 回答 2

2

这是一个有趣的概念。“纯功能”设置中的一个主要并发症是对象身份通常在“纯功能”意义上是不可观察的。IE,如果我复制一个对象或创建一个新的相同对象,在 Java 中预计克隆不是原始对象。但是在功能设置中,期望新的在语义上与旧的相同,即使垃圾收集器会以不同的方式处理它。

因此,如果我们允许对象身份成为语义的一部分,那将是合理的,否则可能不会。在后一种情况下,即使可以找到一个 hack(我想到了一个,如下所述),你很可能会让语言实现到处与你争吵,因为它会做各种各样的事情来利用这个事实该对象身份不应该是可观察的。

一个突然出现在我脑海中的“hack”是使用唯一构造值作为键,这样在大多数情况下,值相等将与引用相等一致。例如,我有一个我在 Haskell 中个人使用的库,其界面中有以下内容:

data Uniq s
getUniq :: IO (Uniq RealWorld)
instance Eq (Uniq s)
instance Ord (Uniq s)

像您描述的哈希映射可能主要使用这些作为键,但即使在这里我也能想到一种可能会破坏的方法:假设用户将键存储在某个数据结构的严格字段中,编译器的“unbox-启用严格字段”优化。如果 'Uniq' 只是机器整数的新类型包装器,则可能不再有 GC 可以指向并说“这是关键”的任何对象;因此,当用户打开钥匙使用它时,地图可能已经忘记了它。(编辑:这个特殊的例子显然可以解决;使 Uniq 的实现成为不能像那样拆箱的东西;关键是它很棘手,因为编译器试图以很多我们可能不会提供的方式提供帮助预计)

TL;DR:我不会说它不能完成,但我怀疑在许多情况下“优化”会被弱哈希映射实现破坏或破坏,除非对象标识被赋予一流的可观察状态。

于 2011-01-17T14:47:36.630 回答
0

从用户的角度来看,纯粹的功能数据结构不能改变。因此,如果我从哈希映射中获得一个键,等待,然后再次获得相同的键,我必须获得相同的值。我可以抓住钥匙,所以它们不会消失。

它可以工作的唯一方法是,如果 API 为我提供了下一代,并且在释放对容器过去版本的所有引用之前不收集值。预计数据结构的用户会定期要求新一代发布弱持有的价值。

编辑(基于评论):我理解你想要的行为,但你不能用释放对象的地图通过这个测试:

FunctionalWeakHashMap map = new FunctionalWeakHashMap();

{ // make scope to make o have no references
   Object o = new SomeObject();
   map["key"] = o;
}  // at this point I lose all references to o, and the reference is weak

// wait as much time as you think it takes for that weak reference to collect, 
// force it, etc

Assert.isNotNull(map["key"]); // this must be true or map is not persistent

我建议这个测试可以通过

FunctionalWeakHashMap map = new FunctionalWeakHashMap();

{ // make scope to make o have no references
   Object o = new SomeObject();
   map["key"] = o;
}  // at this point I lose all references to o, and the reference is weak in the map

// wait as much time as you think it takes for that weak reference to collect, 
// force it, etc

map = map.nextGen();

Assert.isNull(map["key"]); 
于 2011-01-17T14:00:50.723 回答