【发布时间】:2014-06-06 11:20:33
【问题描述】:
我正在尝试在 java 中实现 hash cons,与 String.intern 对字符串所做的类似。即,我希望一个类将数据类型 T 的所有不同值存储在一个集合中,并提供一个 T intern(T t) 方法来检查 t 是否已经在集合中。如果是,则返回集合中的实例,否则将t 添加到集合中并返回。原因是可以使用引用相等来比较结果值,因为从 intern 返回的两个相等值肯定也是同一个实例。
当然,哈希 cons 最明显的候选数据结构是java.util.HashSet<T>。但是,它的接口似乎有缺陷并且不允许有效插入,因为没有方法可以检索已经在集合中的元素,或者如果它不在集合中则插入一个。
使用HashSet 的算法如下所示:
class HashCons<T>{
HashSet<T> set = new HashSet<>();
public T intern(T t){
if(set.contains(t)) {
return ???; // <----- PROBLEM
} else {
set.add(t); // <--- Inefficient, second hash lookup
return t;
}
}
如您所见,问题是双重的:
- 此解决方案效率低下,因为我将访问哈希表两次,一次用于
contains,一次用于add。但是好吧,这可能不会对性能造成太大影响,因为正确的存储桶将在contains之后位于缓存中,因此add不会触发缓存未命中,因此速度非常快。 - 我无法检索集合中已有的元素(参见标记为
PROBLEM的行)。只是没有方法可以检索集合中的元素。所以这是不可能实现的。
我在这里遗漏了什么吗?还是真的不可能用java.util.HashSet 构建一个通常的哈希缺点?
【问题讨论】: