It runs in O(1) expected time, as any hash table (assuming the hash function is decent). It is backed by a HashMap where the key is the Object.
Two objects might have the same hash code, but the HashSet wouldn't think they are identical, unless the equals method for these objects says they are the same (i.e. returns true).
The contains method calls (indirectly) getEntry of HashMap, where key is the Object for which you wish to know if it's in the HashSet.
As you can see below, two objects can be stored in the HashMap/HashSet even if their key is mapped to the same value by the hash function. The method iterates over all keys that have the same hash value, and performs equals on each one to find the matching key.
final Entry<K,V> getEntry(Object key) {
int hash = (key == null) ? 0 : hash(key.hashCode());
for (Entry<K,V> e = table[indexFor(hash, table.length)];
e != null;
e = e.next) {
Object k;
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
return e;
}
return null;
}
Answer from Eran on Stack OverflowIt runs in O(1) expected time, as any hash table (assuming the hash function is decent). It is backed by a HashMap where the key is the Object.
Two objects might have the same hash code, but the HashSet wouldn't think they are identical, unless the equals method for these objects says they are the same (i.e. returns true).
The contains method calls (indirectly) getEntry of HashMap, where key is the Object for which you wish to know if it's in the HashSet.
As you can see below, two objects can be stored in the HashMap/HashSet even if their key is mapped to the same value by the hash function. The method iterates over all keys that have the same hash value, and performs equals on each one to find the matching key.
final Entry<K,V> getEntry(Object key) {
int hash = (key == null) ? 0 : hash(key.hashCode());
for (Entry<K,V> e = table[indexFor(hash, table.length)];
e != null;
e = e.next) {
Object k;
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
return e;
}
return null;
}
The worst-case performance of contains will be O(log n) for Java 8, and O(n) for Java 7, but average case closer to O(1). This is because the hashset is backed by a hashmap, and thus has the same efficiency as hashmap lookup (ie, HashMap.get(...)). The actual mapping in a hashmap is constant time (O(1)), but the need to handle collisions brings the cost to log n. That is, multiple elements that hash to the same array index must be stored in a secondary data structure (aka bucket), and it is this bucket that determines the worst-case performance. In Java, hashmap collision-handling is implemented using a self-balanced tree.
Self-balanced trees guarantee O(log n) for all operations, hence, insertion and lookup in hashmap (and hashset) has a total cost of O(1) + O(log n) = O(log n). The use of a self-balanced tree for collision-handling was introduced in Java 8 as an improvement over chaining (used until java 7), which uses a linked-list, and has a worst case of O(n) for lookup and insertion (as it needs to traverse the list). Notice that chaining would have constant time for insertion (as opposed to lookup), since elements can be added to a linked list in O(1), but the set property (no duplicates) is imposed on the linked-list in the case of hashmap, and it thus need to traverse the linked-list also in the case of insertion to ensure that the element does not already exist in the list/bucket, and we end up with O(n) for both insertion and lookup.
References:
This class implements the Set interface, backed by a hash table (actually a HashMap instance). https://docs.oracle.com/javase/8/docs/api/java/util/HashSet.html
Buckets containing a large number of colliding keys will store their entries in a balanced tree instead of a linked list after certain threshold is reached. (https://www.nagarro.com/en/blog/post/24/performance-improvement-for-hashmap-in-java-8)
As far as I know, it's o(1) but my professor told me it is o(n) He said that it makes a linear search in the set. I don't think it's correct. But I need some proof to show my professor to get my mark from the question. I made some searches and some guys on stackoverflow.com say that it's o(1). So in short how can I prove to my professor it o(1) to get a mark?
" All right guys, I objected and shared my search with him. He confirmed that it's o(1). there is a misunderstood. He taught it's an ArrayList because of my handwriting. So the problem is fixed. Thanks for your all effort."
Time complexity of HashSet.contains in Java - Stack Overflow
Time complexity for searching in java HashSet and TreeSet .
odds of hashcodes for two strings becoming same
Read this: https://dzone.com/articles/what-is-wrong-with-hashcode-in-javalangstring#:~:text=The%20collisions%20in%20hashcode%20are,strings%20have%20the%20same%20hashcode.
how the search in this HashSet works in worst case
HashSet is implemented by wrapping over a HashMap (source: javadoc);
On Java 7, HashMap is implemented by Separate Chaining with LinkedList in each array slot (bucket), so worst case happens when ALL element is chained on a single array slot, making it a linked list with O(n) elements; Searching in a linked list gives worst case time complexity O(k*n) where k is the time complexity of ".equals()" method;
On Java 8, HashMap is implemented by Separate Chaining with Self-balanced BST (e.g. AVL Trees) in each array slot (bucket), so worst case happens when ALL element is chained on a single array slot, making it a balanced BST with O(n) elements; Searching in a balanced BST gives worst case time complexity O(k*lg(n)) where k is the time complexity of ".equals()" method;
I may be wrong tho
More on reddit.comTime complexity of set in Java - Stack Overflow
What is the complexity of contains method of HashSet?
I know in average case the time complexity is O(1) for HashSet and O(lgn) for TreeSet . But for HashSrt when the hashcode for two objects matches then it will search comparing the objects using equal method . But I want to search for strings creating a HashSet<String > . Can some one tell me what are the odds of hashcodes for two strings becoming same and how the search in this HashSet works in worst case . Thank in advance.
i believe its O(n) because you loop over the array, and contains and add should be constant time because its a hash based set. If it were not hash based and required iteration over the entire set to do lookups, the upper bound would be n^2.
Integers are immutable, so the space complexity would be 2n, which I believe simplifies to just n, since constants don't matter.
If you had objects in the array and set, then you would have 2n references and n objects, so you are at 3n, which is still linear (times a constant) space constraints.
EDIT-- yep "This class offers constant time performance for the basic operations (add, remove, contains and size), assuming the hash function disperses the elements properly among the buckets."
see here.
Understanding HashSet is the key of question
According to HashSet in Javadoc,
This class implements the Set interface, backed by a hash table (actually a HashMap instance)...This class offers constant time performance for the basic operations (add, remove, contains and size)
A more complete explain about HashSet https://www.geeksforgeeks.org/hashset-contains-method-in-java/?ref=rp
So the HashSet insert and contains are O(1). ( As HashSet is based on HashMap and Its memory complexity is O(n))
The rest is simple, the main array you are looping is order of O(n) , so the total order of function will be O(n).