直接使用HashCode访问HashSet? (JAVA)
您好,我想知道是否有可能直接访问HashSet的内容,如果你有你正在寻找的对象的Hashcode,有点像使用HashCode作为HashMap中的键。
我想它可能会像这样工作:
MyObject object1 = new MyObject(1);
Set<MyObject> MyHashSet = new HashSet<MyObject>();
MyHashSet.add(object1)
int hash = object1.getHashCode
MyObject object2 = MyHashSet[hash]???
谢谢!
编辑:感谢您的答案。 好吧,我明白我可能会推动HashSet的合约一点,但对于这个特定的项目相等性完全由散列码决定,我确信每个hashcode / hashbucket只会有一个对象。 我很不情愿使用HashMap的原因是因为我需要将我映射的原始ints转换为Integer对象,因为HashMap只将对象作为关键字使用,而且我也担心这可能会影响性能。 还有什么我可以做的实现类似的东西?
HashSet
的通用实现是由HashMap
支持的(相当懒惰地),所以你避免HashMap
的努力可能被打败。
在过早优化是所有邪恶根源的基础上,我建议你最初使用HashMap
,如果int
和Integer
的装箱/拆箱开销确实是一个问题,那么你必须实现(或查找)手工制作的HashSet
使用原始的int
s进行比较。 标准的Java库实际上并不想关心装箱/拆箱成本。 整个语言很早就出售了这个性能问题,在简单性方面取得了相当大的收益 请注意,这些日子(自2004年起!)语言会自动显示“您不需要担心这个”政策的框和取消装箱。 在大多数情况下,这是正确的。
我不知道你的HashKeyedSet
需要多么“丰富”,但是基本的散列表实际上并不难。
HashSet
内部由HashMap
支持,不幸的是,这个问题通过公共API不可用。 但是,我们可以使用反射来访问内部映射,然后使用相同的hashCode
找到一个键:
private static <E> E getFromHashCode(final int hashcode, HashSet<E> set) throws Exception {
// reflection stuff
Field field = set.getClass().getDeclaredField("map");
field.setAccessible(true);
// get the internal map
@SuppressWarnings("unchecked")
Map<E, Object> interalMap = (Map<E, Object>) (field.get(set));
// attempt to find a key with an identical hashcode
for (E elem : interalMap.keySet()) {
if (elem.hashCode() == hashcode) return elem;
}
return null;
}
在一个例子中使用:
HashSet<String> set = new HashSet<>();
set.add("foo"); set.add("bar"); set.add("qux");
int hashcode = "qux".hashCode();
System.out.println(getFromHashCode(hashcode, set));
输出:
qux
这是不可能的,因为HashSet
是一个对象,并没有像这样的公共API。 多个对象也可以具有相同的哈希码,但对象可以不同。
最后只能使用myArray[<index>]
语法访问数组。
上一篇: Accessing a HashSet using the HashCode directly? (Java)
下一篇: Is it possible to print a number formatted with thousand separator in Rust?