我的用例是我正在寻找Java中的数据结构,该结构可以让我查看是否具有相同哈希码的对象位于内部(通过调用contains()),但是我永远不需要遍历元素或检索实际对象。 HashSet很近,但是据我所知,它仍然包含对实际对象的引用,这将浪费内存,因为我永远不需要实际对象的内容。我能想到的最好的选择是Integer类型的HashSet,它仅存储哈希码,但是我想知道是否有一个内置的数据结构可以完成相同的工作(并且只接受一种类型,而不是HashSet的HashSet)。输入Integer,它将接受任何对象的哈希码。
答案 0 :(得分:12)
Bloom filter可以判断对象可能是成员还是绝对不是成员。您可以控制误报的可能性。每个哈希值都映射到一个位。
Guava库提供了an implementation in Java。
答案 1 :(得分:2)
您可以使用IntSet之类的原始集合实现来存储哈希码的值。显然,正如其他人提到的那样,这假定碰撞不是问题。
答案 2 :(得分:1)
如果您想跟踪哈希码是否已经存在并提高内存效率,BitSet
可能会满足您的要求。
看下面的例子:
public static void main(String[] args) {
BitSet hashCodes = new BitSet();
hashCodes.set("1".hashCode());
System.out.println(hashCodes.get("1".hashCode())); // true
System.out.println(hashCodes.get("2".hashCode())); // false
}
BitSet
"implements a vector of bits that grows as needed."。这是一个JDK“ 内置数据结构”,其中不包含“ 对实际对象的引用”。仅在“ 相同的哈希代码位于内部”时存储。
编辑:
正如@Steve在他的评论中提到的,BitSet
的实现不是最有效的内存使用。但是,虽然不是内置的,但还有更多的位设置内存有效实现。
答案 3 :(得分:-1)
没有这样的内置数据结构,因为很少需要这样的数据结构。但是,构建一个很容易。
public class HashCodeSet<T> {
private final HashSet<Integer> hashCodes;
public MyHashSet() {
hashCodes = new HashSet<>();
}
public MyHashSet(int initialCapacity) {
hashCodes = new HashSet<>(initialCapacity);
}
public HashCodeSet(HashCodeSet toCopy) {
hashCodes = new HashSet<>(toCopy.hashCodes);
}
public void add(T element) {
hashCodes.add(element.hashCode());
}
public boolean containsHashCodeOf(T element) {
return hashCodes.contains(element.hashCode());
}
@Override
public boolean equals(o: Object) {
return o == this || o instanceof HashCodeSet &&
((HashCodeSet) o).hashCodes.equals(hashCodes);
}
@Override
public int hashCode() {
return hashCodes.hashCode(); // hash-ception
}
@Override
public String toString() {
return hashCodes.toString();
}
}