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.