Access a HashSet directly with a HashCode? (Java)

Hey. I am wondering if it is possible to directly access the contents of the HashSet if you have a Hashcode for the object you are looking for, sort of using HashCode as the key in the HashMap.

I assume this might work something like this:

MyObject object1 = new MyObject(1); Set<MyObject> MyHashSet = new HashSet<MyObject>(); MyHashSet.add(object1) int hash = object1.getHashCode MyObject object2 = MyHashSet[hash]??? 

Thanks!

edit: Thanks for the answers. Well, I understand that I could push the HashSet contract a bit, but for this particular project, equality is determined solely by the hash code, and I know for sure that there will only be one object per hash code / hashbucket. The reason I was rather reluctant to use HashMap is because I will need to convert the primitive ints to which I map Integer objects, since the HashMap only accepts objects as keys, and I am also worried that this may affect performance. Is there anything else I could do to implement something like this?

+7
java hashcode hashset hash
source share
4 answers

The overall implementation of HashSet supported (rather lazily) by using HashMap , so your attempt to avoid the HashMap is likely to be defeated.

Based on the premise that premature optimization is the root of all evil, I suggest you use HashMap first, and if the overhead of boxing / unboxing int in and out of Integer really a problem, you will have (or find) a manual HashSet using the int primitive for comparisons. The standard Java library really does not want to relate to the cost of boxing / unboxing. The whole language has sold this performance issue for significant benefits in simplicity a long time ago. Please note that these days (since 2004!) The language is automatically placed in the box and unpacked, which shows the policy "you do not need to worry about it." In most cases this is correct.

I don’t know how rich your HashKeyedSet , but the underlying hash table is really not too complicated.

+2
source share

HashSet internally supported by HashMap , which is not accessible through the public API, unfortunately for this issue. However, we can use reflection to access the internal map, and then find the key with an identical 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; } 

Used in the example:

 HashSet<String> set = new HashSet<>(); set.add("foo"); set.add("bar"); set.add("qux"); int hashcode = "qux".hashCode(); System.out.println(getFromHashCode(hashcode, set)); 

Output:

 qux 
+2
source share

This is not possible since the HashSet is an object and it does not have an open API. Also, multiple objects may have the same hash code, but objects may be different.

Finally, access to arrays is only possible using the syntax myArray[<index>] .

0
source share

You can easily write code that will directly access the internal data structures of the HashSet implementation using reflection. Of course, your code will depend on the implementation details of the particular JVM that you are coding. You will also be subject to SecurityManager restrictions (if any).

A typical HashSet implementation uses HashMap as an internal data structure. HashMap has an array that is indexed with a key hash code associated with the index in the array. The hash mapping function is available by calling non-public methods in the implementation - you will need to read the source code and understand it. Once you get into the right bucket, you just need to find (using equals ) the correct bucket entry.

0
source share

All Articles