我能以某种方式检索存储在Java中的Hashset中的密钥吗?

时间:2014-03-05 13:37:40

标签: java hashmap hashset

我正在尝试进行双向A星搜索,我遇到了这个问题。

假设我在散列集H中有一个对象A.假设有另一个对象B,这样A.equals(B)为真(并且它们的散列值也相同),尽管A和B指向不同的对象。现在,当我检查对象B是否在hashset H中时,它会返回true,如预期的那样。但是,现在假设,我想基于此访问对象A中的某些属性,然后我需要访问对象A.请注意,访问B中的相同属性将不起作用,因为它们仅在equals方法下相等,但不指向同一个对象。我怎样才能做到这一点?

一种方法是使用Hashmap,使得值类型与键类型相同,并且每次我将一些键存储在hashmap中时,我都会存储与其值相同的对象。但是,当我真正需要的是密钥本身的副本时,这会产生额外的内存开销。还有其他方法可以达到这个目的吗?

3 个答案:

答案 0 :(得分:4)

我不相信使用HashSet<E>有效地做到这一点。 (当然,你可以列出所有的密钥并检查它们是否相等。)

然而,尽管HashMap方法会恼人,但它实际上不会占用更多内存。 HashSet是使用HashMap实现的(至少在库存JDK 7中),所以每个集合条目都有一个完整的映射条目......并且没有额外的内存来存储值,因为它们' d都只是对同一个对象的引用。

答案 1 :(得分:2)

  

一种方法是使用Hashmap,使得值类型与键类型相同,并且每次我将一些键存储在hashmap中时,我都会存储与其值相同的对象。但是,当我真正需要的是密钥本身的副本时,这会产生额外的存储空间开销。

实际上,在(至少)Java 7中的Java Java SE库中HashSet的实现has a HashMap inside it。因此,您对HashMap的额外内存使用情况的担忧是没有根据的。

以下是源代码的链接:http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7u40-b43/java/util/HashSet.java/

顺便提一下,内部地图声明为HashMap<E, Object>而不是HashMap<E, E>。读者的思考练习:为什么他们这样做?


唯一合理的替代方法(使用HashSet)将迭代set元素,测试每个元素以查看它是否等于您要查找的元素。这显然非常(时间)效率低下。

答案 2 :(得分:0)

你可以迭代HashSet中的所有值并检查B的equals方法。如果迭代器返回一个等于B的对象,你就找到了A.