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
Sets are non-linear unordered data structures. That means you can't retrieve an item in a set using the index as you used to do with lists. However, you can retrieve all elements or an arbitrary element from a set without an explicit index.
HashSet does not have a get method to retrieve elements. HashSet implements the Set interface. The Set is a collection with no duplicates. This interface models the mathematical set abstraction.
HashSet can not guarantee insertion order so no point in get method. What are you missing is implementing equals and use contains() which will iterate and find the object.
Method SummaryReturns a shallow copy of this HashSet instance: the elements themselves are not cloned. Returns true if this set contains the specified element. Returns true if this set contains no elements. Returns an iterator over the elements in this set.
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...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With