Introduction to HashSet: Fast Lookups with Hash Table Backing
Introduction to HashSet: Fast Lookups with Hash Table Backing
Introduction to HashSet
Java में HashSet एक बहुत ही powerful class है जो unique elements को store करने के लिए use की जाती है। ये class Set interface को implement करती है और internally HashMap का use करती है ताकि elements को तेज़ी से access किया जा सके। अगर आप किसी collection में duplicate values से बचना चाहते हैं और fast searching चाहते हैं, तो HashSet best choice है।
Real Life Example
मान लीजिए आपके पास students के roll numbers की list है और आपको यह ensure करना है कि कोई भी roll number दो बार ना आए। ऐसे case में HashSet automatically duplicates को remove कर देगा क्योंकि यह सिर्फ unique values को रखता है।
HashSet Definition and Characteristics
HashSet Java Collection Framework का हिस्सा है और इसका use तब किया जाता है जब आपको fast lookup और unique element storage की जरूरत हो। यह elements को random order में store करता है क्योंकि internally इसका structure Hash Table पर आधारित होता है।
Important Features of HashSet
- Duplicates allow नहीं करता।
- Elements unordered रहते हैं (insertion order maintain नहीं होती)।
- Internally HashMap use करता है।
- Null value एक बार allow करता है।
- Search, Insert, और Delete operations O(1) average time complexity में perform होते हैं।
Internal Working of HashSet
HashSet का core concept hashing पर आधारित है। जब भी कोई element add किया जाता है, तो उसका hashCode() calculate होता है और उसी hash value के basis पर element को Hash Table में रखा जाता है। अगर दो elements का hash code same निकल जाए, तो equals() method से comparison होता है जिससे uniqueness maintain रहे।
Working Process
- हर object का hashCode() निकाला जाता है।
- उस hashCode के base पर bucket decide होती है।
- अगर bucket खाली है तो element insert हो जाता है।
- अगर पहले से element है, तो equals() method से check किया जाता है।
- अगर duplicate है तो ignore होता है, otherwise add हो जाता है।
HashSet Constructor and Syntax
HashSet class के multiple constructors होते हैं जिनसे हम अलग-अलग तरीकों से object बना सकते हैं। यहाँ नीचे syntax और commonly used constructors दिए गए हैं।
Syntax
HashSet<Type> set = new HashSet<>();
Common Constructors
- HashSet() – Default capacity (16) और load factor (0.75) के साथ HashSet बनाता है।
- HashSet(int capacity) – Custom initial capacity define करने के लिए।
- HashSet(int capacity, float loadFactor) – Capacity और load factor दोनों specify करने के लिए।
- HashSet(Collection c) – किसी existing collection से HashSet बनाने के लिए।
HashSet Basic Operations
HashSet में कुछ basic और frequently used operations होते हैं जो real-world programming में बहुत काम आते हैं। आइए एक-एक करके समझते हैं।
1. Adding Elements
HashSet<String> cities = new HashSet<>();
cities.add("Delhi");
cities.add("Mumbai");
cities.add("Delhi"); // duplicate ignored
ऊपर के code में “Delhi” दो बार add किया गया है, लेकिन HashSet duplicate को allow नहीं करता, इसलिए second entry ignore हो जाएगी।
2. Removing Elements
cities.remove("Mumbai");
यह method “Mumbai” को HashSet से remove कर देगा अगर वो exist करता है।
3. Checking Elements
boolean present = cities.contains("Delhi");
अगर “Delhi” HashSet में है तो true return करेगा, नहीं तो false।
4. Size of HashSet
int size = cities.size();
यह method total unique elements की count बताती है।
5. Clearing HashSet
cities.clear();
यह method सारे elements को HashSet से remove कर देता है।
Iteration in HashSet
HashSet में elements unordered रहते हैं, लेकिन हम उन्हें iterate कर सकते हैं Iterator या for-each loop की मदद से।
Using for-each loop
for(String city : cities) {
System.out.println(city);
}
Using Iterator
Iterator<String> it = cities.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
Performance and Time Complexity
HashSet का performance काफी efficient होता है क्योंकि यह hashing पर आधारित है। नीचे table में average और worst case complexities दी गई हैं।
| Operation | Average Time Complexity | Worst Case |
|---|---|---|
| add() | O(1) | O(n) |
| remove() | O(1) | O(n) |
| contains() | O(1) | O(n) |
| iteration() | O(n) | O(n) |
Average case में performance बहुत तेज़ रहता है क्योंकि collisions rare होती हैं। लेकिन अगर बहुत सारे elements का hash same आ जाए तो performance degrade हो सकता है।
HashSet vs TreeSet vs LinkedHashSet
Java में Set interface को implement करने वाली कई classes हैं जैसे HashSet, LinkedHashSet और TreeSet। सभी का behavior थोड़ा अलग होता है।
| Feature | HashSet | LinkedHashSet | TreeSet |
|---|---|---|---|
| Order | Unordered | Insertion order maintained | Sorted order |
| Performance | Fastest | Slower than HashSet | Slowest |
| Null allowed | Yes (once) | Yes (once) | No |
| Internal structure | Hash Table | Linked Hash Table | Red-Black Tree |
Advantages of HashSet
- Duplicate data automatically remove होता है।
- Search, insert और delete बहुत तेज़ होते हैं।
- Memory utilization efficient रहती है।
- Null value support करता है।
Limitations of HashSet
- Elements unordered रहते हैं, इसलिए sequence lost हो जाता है।
- Thread-safe नहीं है — external synchronization की जरूरत पड़ती है।
- Custom objects के लिए equals() और hashCode() को properly override करना जरूरी है।
Use Cases of HashSet
- Duplicate-free data maintain करने के लिए।
- Fast membership checking के लिए (जैसे “is this user already registered?”)।
- Large data sets में quick lookup operations के लिए।
- Unique keyword collection, email list, या tags store करने के लिए।
Example Program
नीचे एक complete example दिया गया है जो HashSet की working को practically दिखाता है।
import java.util.*;
public class HashSetExample {
public static void main(String[] args) {
HashSet<String> fruits = new HashSet<>();
fruits.add("Apple");
fruits.add("Banana");
fruits.add("Mango");
fruits.add("Apple"); // duplicate ignored
System.out.println("Fruits in HashSet: " + fruits);
if(fruits.contains("Mango")) {
System.out.println("Mango is present!");
}
fruits.remove("Banana");
System.out.println("After removal: " + fruits);
}
}
Best Practices for HashSet
- जब भी custom objects store करें, हमेशा equals() और hashCode() override करें।
- अगर insertion order maintain करनी हो, तो LinkedHashSet use करें।
- Thread-safe version चाहिए तो Collections.synchronizedSet() का use करें।
- Large data के लिए initial capacity बढ़ा सकते हैं ताकि rehashing कम हो।
Summary
HashSet Java में एक fast, efficient और duplicate-free data structure है जो hashing mechanism पर आधारित है। यह memory efficient होते हुए भी fast lookup, insertion और deletion provide करता है। Exam point of view से, HashSet के concepts जैसे hashCode(), equals(), internal working और comparison with TreeSet/LinkedHashSet बहुत important हैं।