1. Learning Outcomes#
इस chapter के बाद आप:
- समझ पाएँगे कि
LinkedHashSetक्या है और इसकी आवश्यकता क्यों पड़ती है। - समझ पाएँगे कि यह uniqueness के साथ predictable encounter order कैसे बनाए रखता है।
HashSetऔरLinkedHashSetके बीच सही अंतर समझ पाएँगे।- समझ पाएँगे कि
LinkedHashSetinternally hash-based lookup और linked encounter order दोनों maintain करता है। - empty
LinkedHashSetऔर किसी दूसरे collection सेLinkedHashSetबना पाएँगे। - duplicate elements और एक
nullelement के behavior को समझ पाएँगे। - समझ पाएँगे कि सामान्य
add()existing element की position क्यों नहीं बदलता। - Java 21+ में
addFirst(),addLast(),getFirst(),getLast(),removeFirst(), औरremoveLast()का उपयोग कर पाएँगे। reversed()से reverse-ordered backed view बना पाएँगे।LinkedHashSetकी basic performance और ordering overhead समझ पाएँगे।- interview में आने वाले common
LinkedHashSettraps पहचान पाएँगे।
2. LinkedHashSet की आवश्यकता क्यों पड़ती है?#
मान लीजिए हमारे पास skills की list है:
Java, SQL, Git, Java
हमें दो चीजें चाहिए:
- duplicate skill नहीं चाहिए।
- skills उसी order में चाहिए जिस order में पहली बार जोड़ी गई थीं।
सिर्फ Set का concept uniqueness देता है।
लेकिन हर Set implementation predictable encounter order नहीं देता।
यहीं LinkedHashSet उपयोगी होता है।
LinkedHashSet का मुख्य combination है: unique elements + well-defined encounter order.
अगर elements इस क्रम में add किए जाएँ:
Java → SQL → Git
तो सामान्य iteration में वही encounter order दिखाई देगा:
Java → SQL → Git
यह sorting नहीं है।
यह बहुत महत्वपूर्ण अंतर है।
अगर हम numbers इस क्रम में add करें:
30, 10, 20
तो LinkedHashSet उन्हें automatically 10, 20, 30 नहीं करेगा।
सामान्य insertion-order behavior में encounter order रहेगा:
30, 10, 20
3. LinkedHashSet कहाँ fit होता है?#
Java Collections Framework में LinkedHashSet एक hash-based Set है जिसमें defined encounter order भी होता है।
Java 21+ में यह SequencedSet भी implement करता है।
इस relationship को सरल रूप में देखें:
Rendering diagram…
Diagram could not be rendered.
यहाँ दो बातें याद रखें:
LinkedHashSetextendsHashSet.- Java 21+ में
LinkedHashSetimplementsSequencedSet.
HashSet से इसे hash-based uniqueness और lookup behavior मिलता है।
इसके ऊपर LinkedHashSet encounter order maintain करता है।
SequencedSet के कारण Java 21+ में first और last side से काम करने वाले operations भी उपलब्ध हैं।
4. Encounter order का अर्थ#
Encounter order वह defined order है जिसमें collection के elements encounter किए जाते हैं।
LinkedHashSet के सामान्य behavior में यह insertion order होता है।
उदाहरण:
import java.util.LinkedHashSet;
public class Main {
public static void main(String[] args) {
LinkedHashSet<String> skills = new LinkedHashSet<>();
skills.add("Java");
skills.add("SQL");
skills.add("Git");
System.out.println(skills);
}
}Expected Output#
[Java, SQL, Git]पहले Java add हुआ।
फिर SQL।
फिर Git।
इसलिए iteration और printed representation उसी encounter order को दिखाते हैं।
LinkedHashSet का "ordered" होना sorted होने के समान नहीं है। यह सामान्यतः insertion-based encounter order preserve करता है।
5. Internally यह कैसे काम करता है?#
एक beginner के लिए इसका high-level mental model दो भागों में समझना पर्याप्त है।
1. Hash-based structure#
Hash-based structure यह पता लगाने में मदद करता है कि:
- element पहले से मौजूद है या नहीं।
- element कहाँ खोजा जाए।
- duplicate add होना चाहिए या reject होना चाहिए।
2. Doubly-linked encounter order#
इसके साथ entries के बीच order relationship भी maintain होती है।
सरल conceptual picture:
Rendering diagram…
Diagram could not be rendered.
Hash-based हिस्सा membership और lookup में मदद करता है।
Linked relationship encounter order को preserve करता है।
इसलिए LinkedHashSet दो महत्वपूर्ण गुण combine करता है:
- hash-based set behavior
- predictable encounter order
इस अतिरिक्त ordering structure की वजह से HashSet की तुलना में कुछ extra memory overhead होता है।
6. Empty LinkedHashSet बनाना#
सबसे सामान्य तरीका:
import java.util.LinkedHashSet;
public class Main {
public static void main(String[] args) {
LinkedHashSet<String> technologies = new LinkedHashSet<>();
technologies.add("Java");
technologies.add("Spring");
technologies.add("SQL");
System.out.println(technologies);
}
}Expected Output#
[Java, Spring, SQL]यहाँ LinkedHashSet initially empty था।
Elements जिस क्रम में add हुए, encounter order उसी क्रम में बना।
7. किसी दूसरे Collection से LinkedHashSet बनाना#
कई बार हमारे पास पहले से कोई collection होता है।
उदाहरण के लिए एक List जिसमें duplicate values हैं।
हम उससे LinkedHashSet बना सकते हैं।
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<String> skills =
Arrays.asList("Java", "SQL", "Java", "Git");
LinkedHashSet<String> uniqueSkills =
new LinkedHashSet<>(skills);
System.out.println(uniqueSkills);
}
}Expected Output#
[Java, SQL, Git]यहाँ:
- पहला
Javaरखा गया। SQLरखा गया।- दूसरा
Javaduplicate होने के कारण अलग element के रूप में नहीं जुड़ा। Gitरखा गया।
इसलिए result में uniqueness भी मिली और source collection के encounter sequence के अनुसार पहली occurrence का order भी preserve हुआ।
8. Duplicate elements क्यों reject होते हैं?#
LinkedHashSet आखिरकार एक Set है।
इसलिए एक logical element केवल एक बार मौजूद हो सकता है।
उदाहरण:
import java.util.LinkedHashSet;
public class Main {
public static void main(String[] args) {
LinkedHashSet<String> skills = new LinkedHashSet<>();
skills.add("Java");
skills.add("SQL");
skills.add("Java");
System.out.println(skills);
}
}Expected Output#
[Java, SQL]दूसरा Java नया unique element नहीं है।
इसलिए size नहीं बढ़ता।
add() method boolean result भी देता है।
नया element successfully add हुआ तो true मिलता है।
अगर equal element पहले से मौजूद है तो सामान्यतः false मिलता है।
import java.util.LinkedHashSet;
public class Main {
public static void main(String[] args) {
LinkedHashSet<String> skills = new LinkedHashSet<>();
System.out.println(skills.add("Java"));
System.out.println(skills.add("Java"));
}
}Expected Output#
true
false9. Duplicate detection और equals() / hashCode()#
आप पहले Set के context में equals() और hashCode() contract सीख चुके हैं।
यहाँ वही rule लागू होता है।
LinkedHashSet uniqueness तय करने के लिए hash-based mechanism का उपयोग करता है।
इसलिए custom objects के साथ सही equals() और hashCode() implementation बहुत महत्वपूर्ण होती है।
सिर्फ encounter order देखकर यह मत सोचिए कि duplicate checking list की तरह होती है। LinkedHashSet अभी भी hash-based Set है।
10. Existing element को दोबारा add() करने पर क्या होता है?#
यह एक महत्वपूर्ण interview trap है।
मान लें encounter order है:
Java → SQL → Git
अब हम फिर से:
skills.add("SQL");करते हैं।
क्या SQL सबसे अंत में चला जाएगा?
नहीं।
सामान्य add() existing element को दोबारा insert करके उसकी encounter position नहीं बदलता।
import java.util.LinkedHashSet;
public class Main {
public static void main(String[] args) {
LinkedHashSet<String> skills = new LinkedHashSet<>();
skills.add("Java");
skills.add("SQL");
skills.add("Git");
boolean added = skills.add("SQL");
System.out.println(added);
System.out.println(skills);
}
}Expected Output#
false
[Java, SQL, Git]SQL पहले से मौजूद था।
इसलिए:
- नया element add नहीं हुआ।
add()नेfalsereturn किया।SQLकी existing encounter position नहीं बदली।
Java 21+ में existing element को explicit तरीके से first या last position पर move करने के लिए अलग methods उपलब्ध हैं। उन्हें हम आगे देखेंगे।
11. null element का behavior#
LinkedHashSet एक null element को support करता है।
लेकिन duplicate rule null पर भी लागू होता है।
import java.util.LinkedHashSet;
public class Main {
public static void main(String[] args) {
LinkedHashSet<String> values = new LinkedHashSet<>();
values.add("Java");
values.add(null);
values.add("SQL");
values.add(null);
System.out.println(values);
}
}Expected Output#
[Java, null, SQL]पहला null add हुआ।
दूसरा null duplicate है।
इसलिए केवल एक null मौजूद रहता है।
12. Java 21+: SequencedSet क्यों महत्वपूर्ण है?#
Java 21 में sequenced collection interfaces introduce किए गए।
LinkedHashSet अब SequencedSet implement करता है।
इससे defined encounter order वाले set के first और last ends के साथ सीधे काम करना आसान हो गया।
मुख्य methods हैं:
| Method | काम |
|---|---|
addFirst() |
element को encounter order की शुरुआत में रखता है |
addLast() |
element को encounter order के अंत में रखता है |
getFirst() |
first element देता है |
getLast() |
last element देता है |
removeFirst() |
first element remove करके return करता है |
removeLast() |
last element remove करके return करता है |
reversed() |
reverse encounter-order view देता है |
ये sequencing methods Java 21+ के context में विशेष रूप से महत्वपूर्ण हैं। Older Java releases में LinkedHashSet का सामान्य insertion-order behavior था, लेकिन ये standardized sequenced operations उपलब्ध नहीं थे।
13. addFirst() का उपयोग#
मान लें set है:
Java → SQL → Git
हमें Docker को सबसे पहले रखना है।
Java 21+:
import java.util.LinkedHashSet;
public class Main {
public static void main(String[] args) {
LinkedHashSet<String> skills = new LinkedHashSet<>();
skills.add("Java");
skills.add("SQL");
skills.add("Git");
skills.addFirst("Docker");
System.out.println(skills);
}
}Expected Output#
[Docker, Java, SQL, Git]Docker नया element था।
addFirst() ने उसे first encounter position पर रखा।
14. addLast() का उपयोग#
addLast() element को last encounter position पर रखता है।
import java.util.LinkedHashSet;
public class Main {
public static void main(String[] args) {
LinkedHashSet<String> skills = new LinkedHashSet<>();
skills.add("Java");
skills.add("SQL");
skills.addLast("Git");
System.out.println(skills);
}
}Expected Output#
[Java, SQL, Git]इस simple case में normal add() और addLast() का visible result समान लग सकता है।
लेकिन addLast() का खास महत्व तब स्पष्ट होता है जब element पहले से set में मौजूद हो।
15. Existing element को addFirst() से reposition करना#
यही behavior सामान्य add() से अलग है।
import java.util.LinkedHashSet;
public class Main {
public static void main(String[] args) {
LinkedHashSet<String> skills = new LinkedHashSet<>();
skills.add("Java");
skills.add("SQL");
skills.add("Git");
skills.addFirst("Git");
System.out.println(skills);
}
}Expected Output#
[Git, Java, SQL]Git duplicate के रूप में दूसरी copy नहीं बना।
वही existing element first encounter position पर reposition हुआ।
यानी uniqueness बनी रही।
सिर्फ encounter position बदली।
16. Existing element को addLast() से reposition करना#
import java.util.LinkedHashSet;
public class Main {
public static void main(String[] args) {
LinkedHashSet<String> skills = new LinkedHashSet<>();
skills.add("Java");
skills.add("SQL");
skills.add("Git");
skills.addLast("Java");
System.out.println(skills);
}
}Expected Output#
[SQL, Git, Java]Java की duplicate copy नहीं बनी।
Existing Java last encounter position पर move हुआ।
add() और sequencing methods का अंतर#
| Operation | Existing element मिलने पर |
|---|---|
add(element) |
duplicate add नहीं करता और सामान्यतः position नहीं बदलता |
addFirst(element) |
element को first position पर reposition कर सकता है |
addLast(element) |
element को last position पर reposition कर सकता है |
यह distinction interview में बहुत पूछा जा सकता है।
17. First और Last elements access करना#
Java 21+ में getFirst() और getLast() encounter order के दोनों ends access करने देते हैं।
import java.util.LinkedHashSet;
public class Main {
public static void main(String[] args) {
LinkedHashSet<String> skills = new LinkedHashSet<>();
skills.add("Java");
skills.add("SQL");
skills.add("Git");
System.out.println(skills.getFirst());
System.out.println(skills.getLast());
}
}Expected Output#
Java
GitJava first encounter element है।
Git last encounter element है।
Empty set पर getFirst() या getLast() call करने पर NoSuchElementException आ सकता है। इसलिए application logic में empty state को ध्यान में रखना चाहिए।
18. First element remove करना#
removeFirst() first encounter element को remove करता है और वही element return करता है।
import java.util.LinkedHashSet;
public class Main {
public static void main(String[] args) {
LinkedHashSet<String> skills = new LinkedHashSet<>();
skills.add("Java");
skills.add("SQL");
skills.add("Git");
String removed = skills.removeFirst();
System.out.println(removed);
System.out.println(skills);
}
}Expected Output#
Java
[SQL, Git]19. Last element remove करना#
removeLast() last encounter element remove करता है।
import java.util.LinkedHashSet;
public class Main {
public static void main(String[] args) {
LinkedHashSet<String> skills = new LinkedHashSet<>();
skills.add("Java");
skills.add("SQL");
skills.add("Git");
String removed = skills.removeLast();
System.out.println(removed);
System.out.println(skills);
}
}Expected Output#
Git
[Java, SQL]Empty set पर removeFirst() या removeLast() भी NoSuchElementException दे सकता है।
20. reversed() से reverse encounter-order view#
Java 21+ में reversed() बहुत उपयोगी method है।
मान लें original encounter order है:
Java → SQL → Git
Reverse view होगा:
Git → SQL → Java
import java.util.LinkedHashSet;
import java.util.SequencedSet;
public class Main {
public static void main(String[] args) {
LinkedHashSet<String> skills = new LinkedHashSet<>();
skills.add("Java");
skills.add("SQL");
skills.add("Git");
SequencedSet<String> reverseView = skills.reversed();
System.out.println(skills);
System.out.println(reverseView);
}
}Expected Output#
[Java, SQL, Git]
[Git, SQL, Java]यहाँ सबसे महत्वपूर्ण शब्द है:
view
reversed() एक independent copied set बनाने का concept नहीं है।
यह original set का reverse-ordered view देता है।
21. Reversed view original set से backed होता है#
अगर reverse view में supported modification की जाए, तो उसका effect original set में भी दिखाई देता है।
import java.util.LinkedHashSet;
import java.util.SequencedSet;
public class Main {
public static void main(String[] args) {
LinkedHashSet<String> skills = new LinkedHashSet<>();
skills.add("Java");
skills.add("SQL");
skills.add("Git");
SequencedSet<String> reverseView = skills.reversed();
reverseView.remove("SQL");
System.out.println(reverseView);
System.out.println(skills);
}
}Expected Output#
[Git, Java]
[Java, Git]SQL reverse view से remove किया गया।
क्योंकि view original set से backed है, SQL original skills set से भी remove हो गया।
इसी प्रकार original set में होने वाले changes reverse view में reflect होते हैं।
reversed() को copy समझना गलत है। LinkedHashSet के लिए यह original set से जुड़ा reverse-ordered view है।
22. Encounter order को एक flow में समझें#
Rendering diagram…
Diagram could not be rendered.
यह flow तीन अलग बातें स्पष्ट करता है:
- New elements सामान्यतः insertion sequence में आते हैं।
- Existing element पर normal
add()encounter position नहीं बदलता। - Java 21+ का
addFirst()existing element को explicit position पर move कर सकता है।
23. Basic operation performance#
LinkedHashSet hash-based collection है।
अच्छी hash distribution की सामान्य स्थिति में basic operations की expected performance:
| Operation | Expected Time |
|---|---|
add() |
O(1) |
contains() |
O(1) |
remove() |
O(1) |
यह expected performance है।
इसे absolute guarantee के रूप में नहीं देखना चाहिए क्योंकि hashing behavior data और hash distribution पर निर्भर करता है।
24. Iteration performance#
LinkedHashSet की iteration encounter-order linked structure पर चलती है।
इसलिए iteration cost set में मौजूद elements की संख्या के proportional होती है।
अगर set में n elements हैं तो iteration broadly O(n) है।
यह एक practical advantage भी हो सकता है क्योंकि iteration underlying hash-table capacity पर निर्भर रहने के बजाय actual set size के अनुसार चलती है।
25. Ordering की कीमत क्या है?#
Predictable order free में नहीं मिलता।
LinkedHashSet को hash-based structure के साथ ordering links भी maintain करने पड़ते हैं।
इसलिए HashSet की तुलना में:
- extra ordering metadata चाहिए।
- memory overhead अधिक हो सकता है।
- insertion/removal के दौरान encounter-order links भी maintain करने पड़ते हैं।
इसके बदले हमें predictable iteration order मिलता है।
अगर order की जरूरत ही नहीं है, तो सिर्फ order के लिए LinkedHashSet चुनना आवश्यक नहीं। लेकिन uniqueness के साथ predictable encounter order चाहिए तो यह बहुत उपयोगी choice है।
26. HashSet vs LinkedHashSet#
| Feature | HashSet |
LinkedHashSet |
|---|---|---|
| Unique elements | Yes | Yes |
| Hash-based lookup | Yes | Yes |
| Predictable encounter order | No defined encounter order | Yes |
| Normal insertion-order preservation | Not guaranteed | Yes |
| Java 21+ sequenced first/last operations | No | Yes |
One null element |
Supported | Supported |
Basic add / contains / remove |
Expected O(1) | Expected O(1) |
| Additional ordering memory | Lower | Higher |
| Best fit | Uniqueness when order does not matter | Uniqueness plus predictable encounter order |
27. Practical example: unique recently arranged options#
मान लें application में user ने technologies इस क्रम में choose कीं:
Java, SQL, Git
आप duplicates नहीं चाहते।
लेकिन display करते समय original encounter order भी preserve करना चाहते हैं।
LinkedHashSet इस requirement के लिए natural choice है।
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<String> selected =
Arrays.asList("Java", "SQL", "Java", "Git", "SQL");
LinkedHashSet<String> uniqueSelection =
new LinkedHashSet<>(selected);
System.out.println(uniqueSelection);
}
}Expected Output#
[Java, SQL, Git]Duplicates हट गए।
पहली बार encounter हुए elements का order बना रहा।
यही LinkedHashSet की सबसे सामान्य practical strength है।
28. कब LinkedHashSet चुनें?#
LinkedHashSet तब अच्छा fit है जब दोनों requirements साथ हों:
Requirement 1: Uniqueness#
Duplicate logical elements नहीं चाहिए।
Requirement 2: Predictable encounter order#
Iteration/display/process का order defined होना चाहिए।
Typical situations:
- unique menu selections को entry order में रखना
- duplicate tags हटाकर original sequence रखना
- ordered unique processing
- किसी दूसरे collection की unique ordered copy बनाना
- first/last ordered-set operations की आवश्यकता होना
अगर encounter order matter नहीं करता तो HashSet पर्याप्त हो सकता है।
29. Synchronization के बारे में#
LinkedHashSet synchronized collection नहीं है।
इसका मतलब यह नहीं कि इसे कभी multiple threads के साथ use नहीं किया जा सकता।
मतलब यह है कि built-in automatic thread synchronization इसकी primary behavior का हिस्सा नहीं है।
जरूरत होने पर synchronized wrapper बनाया जा सकता है:
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
public class Main {
public static void main(String[] args) {
Set<String> skills =
Collections.synchronizedSet(new LinkedHashSet<>());
skills.add("Java");
skills.add("SQL");
System.out.println(skills);
}
}Expected Output#
[Java, SQL]Concurrent iteration जैसी situations में synchronization discipline अलग से महत्वपूर्ण हो सकती है।
इस chapter के लिए मुख्य बात यही याद रखें:
Plain LinkedHashSet को automatically thread-safe collection न मानें।
30. Common LinkedHashSet interview traps#
Trap 1: Ordered का मतलब sorted है#
गलत।
LinkedHashSet values को automatically sort नहीं करता।
यह defined encounter order maintain करता है, जो सामान्यतः insertion order होता है।
Trap 2: Existing element को add() करने से वह last में चला जाता है#
गलत।
Normal add() existing element की encounter position को सामान्यतः नहीं बदलता।
Java 21+ में explicit repositioning के लिए addFirst() और addLast() उपयोग किए जा सकते हैं।
Trap 3: LinkedHashSet duplicates allow करता है क्योंकि order maintain करता है#
गलत।
यह अभी भी Set है।
Uniqueness fundamental rule है।
Trap 4: reversed() नई independent copy बनाता है#
गलत।
यह reverse-ordered backed view देता है।
Trap 5: LinkedHashSet केवल linked list है#
गलत।
यह hash-based set behavior और linked encounter-order structure combine करता है।
Trap 6: Java 21 sequencing methods सभी historical Java versions में थे#
गलत।
SequencedSet और standardized first/last sequencing operations Java 21+ context से संबंधित हैं।
Trap 7: Empty set पर getFirst() हमेशा null देता है#
गलत।
Empty collection पर getFirst() और related end-access/removal operations NoSuchElementException दे सकते हैं।
31. Recap#
इस chapter से सबसे महत्वपूर्ण बातें:
LinkedHashSetunique elements रखता है।- यह predictable encounter order maintain करता है।
- सामान्य behavior insertion order preserve करता है।
- यह
HashSetको extend करता है। - Java 21+ में यह
SequencedSetimplement करता है। - internally hash-based lookup और doubly-linked encounter order का combination होता है।
- duplicate elements reject होते हैं।
- एक
nullelement supported है। - normal
add()existing element की position नहीं बदलता। addFirst()औरaddLast()existing element को reposition कर सकते हैं।getFirst()औरgetLast()encounter-order ends access करते हैं।removeFirst()औरremoveLast()ends से element remove करते हैं।reversed()reverse-ordered backed view देता है।- basic
add,contains, औरremoveexpected O(1) operations हैं। - iteration set size के proportional होती है।
- predictable ordering के बदले
HashSetकी तुलना में additional overhead आता है। - plain
LinkedHashSetsynchronized नहीं है।
जब requirement हो "duplicates नहीं चाहिए, लेकिन order predictable रहना चाहिए", तब LinkedHashSet Java Collections Framework की महत्वपूर्ण choices में से एक है।