Java: Retrieving an element from a HashSet

Hoping someone can explain why I cannot retrieve an element from a HashSet.

Consider my HashSet containing a list of MyHashObjects with their hashCode() and equals() methods overridden correctly.

What I was hoping to do was to construct a MyHashObject myself, and set the relevant hash code properties to certain values. I can query the HashSet to see if there "equivalent" objects in the set using the contains() method. So even though contains() returns true for the 2 objects, they may not be == true.

How come then there is no get() method similar to how the contains() works?

Interested to know the thinking behind this API decision


If you know what element you want to retrieve, then you already have the element. The only question for a Set to answer, given an element, is whether it contains() it or not.

If you want to iterator over the elements, just use a Set.iterator().

It sounds like what you're trying to do is designate a canonical element for an equivalence class of elements. You can use a Map<MyObject,MyObject> to do this. See this SO question or this one for a discussion.

If you are really determined to find an element that .equals() your original element with the constraint that you MUST use the HashSet, I think you're stuck with iterating over it and checking equals() yourself. The API doesn't let you grab something by its hash code. So you could do:

MyObject findIfPresent(MyObject source, HashSet<MyObject> set)
{
   if (set.contains(source)) {
      for (MyObject obj : set) {
        if (obj.equals(source)) 
          return obj;
      } 
   }

  return null;
}

Brute force and O(n) ugly, but if that's what you need to do...


You can HashMap<MyHashObject,MyHashObject> instead of HashSet<MyHashObject>.

Calling ContainsKey() on your "reconstructed" MyHashObject will first hashCode()-check the collection, and if a duplicate hashcode is hit, finally equals()-check your "reconstructed" against the original, at which you can retrieve the original using get()

This is O(1) but the downside is you will likely have to override both equals() and hashCode() methods.


It sounds like you're essentially trying to use the hash code as a key in a map (which is what HashSets do behind the scenes). You could just do it explicitly, by declaring HashMap<Integer, MyHashObject>.

There is no get for HashSets because typically the object you would supply to the get method as a parameter is the same object you would get back.