是否存在仅存储哈希码而不存储实际对象的数据结构?

时间:2019-03-15 21:15:54

标签: java hashset

我的用例是我正在寻找Java中的数据结构,该结构可以让我查看是否具有相同哈希码的对象位于内部(通过调用contains()),但是我永远不需要遍历元素或检索实际对象。 HashSet很近,但是据我所知,它仍然包含对实际对象的引用,这将浪费内存,因为我永远不需要实际对象的内容。我能想到的最好的选择是Integer类型的HashSet,它仅存储哈希码,但是我想知道是否有一个内置的数据结构可以完成相同的工作(并且只接受一种类型,而不是HashSet的HashSet)。输入Integer,它将接受任何对象的哈希码。

4 个答案:

答案 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();
    }
}