Printing is unavailable

This course is licensed for personal online viewing only.

Public preview • CL-P000000-C41-L1429-46057E87

Home Dashboard
Chapter 79 · Module 9 — Java Collections Framework

LinkedHashSet and Encounter-Order Preservation

Priority
  • JobHigh
  • InterviewHigh
  • DevelopmentMedium
3,834
words
22
min read
3
tools

1. Learning Outcomes#

इस chapter के बाद आप:

  • समझ पाएँगे कि LinkedHashSet क्या है और इसकी आवश्यकता क्यों पड़ती है।
  • समझ पाएँगे कि यह uniqueness के साथ predictable encounter order कैसे बनाए रखता है।
  • HashSet और LinkedHashSet के बीच सही अंतर समझ पाएँगे।
  • समझ पाएँगे कि LinkedHashSet internally hash-based lookup और linked encounter order दोनों maintain करता है।
  • empty LinkedHashSet और किसी दूसरे collection से LinkedHashSet बना पाएँगे।
  • duplicate elements और एक null element के 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 LinkedHashSet traps पहचान पाएँगे।

2. LinkedHashSet की आवश्यकता क्यों पड़ती है?#

मान लीजिए हमारे पास skills की list है:

Java, SQL, Git, Java

हमें दो चीजें चाहिए:

  1. duplicate skill नहीं चाहिए।
  2. skills उसी order में चाहिए जिस order में पहली बार जोड़ी गई थीं।

सिर्फ Set का concept uniqueness देता है।

लेकिन हर Set implementation predictable encounter order नहीं देता।

यहीं LinkedHashSet उपयोगी होता है।

Key Idea

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 को सरल रूप में देखें:

Visual Diagram80%

Rendering diagram…

यहाँ दो बातें याद रखें:

  • LinkedHashSet extends HashSet.
  • Java 21+ में LinkedHashSet implements SequencedSet.

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 होता है।

उदाहरण:

JAVA
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#

TEXT
[Java, SQL, Git]

पहले Java add हुआ।

फिर SQL।

फिर Git।

इसलिए iteration और printed representation उसी encounter order को दिखाते हैं।

Remember

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:

Visual Diagram80%

Rendering diagram…

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 बनाना#

सबसे सामान्य तरीका:

JAVA
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#

TEXT
[Java, Spring, SQL]

यहाँ LinkedHashSet initially empty था।

Elements जिस क्रम में add हुए, encounter order उसी क्रम में बना।

7. किसी दूसरे Collection से LinkedHashSet बनाना#

कई बार हमारे पास पहले से कोई collection होता है।

उदाहरण के लिए एक List जिसमें duplicate values हैं।

हम उससे LinkedHashSet बना सकते हैं।

JAVA
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#

TEXT
[Java, SQL, Git]

यहाँ:

  • पहला Java रखा गया।
  • SQL रखा गया।
  • दूसरा Java duplicate होने के कारण अलग element के रूप में नहीं जुड़ा।
  • Git रखा गया।

इसलिए result में uniqueness भी मिली और source collection के encounter sequence के अनुसार पहली occurrence का order भी preserve हुआ।

8. Duplicate elements क्यों reject होते हैं?#

LinkedHashSet आखिरकार एक Set है।

इसलिए एक logical element केवल एक बार मौजूद हो सकता है।

उदाहरण:

JAVA
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#

TEXT
[Java, SQL]

दूसरा Java नया unique element नहीं है।

इसलिए size नहीं बढ़ता।

add() method boolean result भी देता है।

नया element successfully add हुआ तो true मिलता है।

अगर equal element पहले से मौजूद है तो सामान्यतः false मिलता है।

JAVA
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#

TEXT
true
false

9. Duplicate detection और equals() / hashCode()#

आप पहले Set के context में equals() और hashCode() contract सीख चुके हैं।

यहाँ वही rule लागू होता है।

LinkedHashSet uniqueness तय करने के लिए hash-based mechanism का उपयोग करता है।

इसलिए custom objects के साथ सही equals() और hashCode() implementation बहुत महत्वपूर्ण होती है।

Common Mistake

सिर्फ encounter order देखकर यह मत सोचिए कि duplicate checking list की तरह होती है। LinkedHashSet अभी भी hash-based Set है।

10. Existing element को दोबारा add() करने पर क्या होता है?#

यह एक महत्वपूर्ण interview trap है।

मान लें encounter order है:

Java → SQL → Git

अब हम फिर से:

JAVA
skills.add("SQL");

करते हैं।

क्या SQL सबसे अंत में चला जाएगा?

नहीं।

सामान्य add() existing element को दोबारा insert करके उसकी encounter position नहीं बदलता।

JAVA
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#

TEXT
false
[Java, SQL, Git]

SQL पहले से मौजूद था।

इसलिए:

  • नया element add नहीं हुआ।
  • add() ने false return किया।
  • 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 पर भी लागू होता है।

JAVA
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#

TEXT
[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 देता है
Note

ये sequencing methods Java 21+ के context में विशेष रूप से महत्वपूर्ण हैं। Older Java releases में LinkedHashSet का सामान्य insertion-order behavior था, लेकिन ये standardized sequenced operations उपलब्ध नहीं थे।

13. addFirst() का उपयोग#

मान लें set है:

Java → SQL → Git

हमें Docker को सबसे पहले रखना है।

Java 21+:

JAVA
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#

TEXT
[Docker, Java, SQL, Git]

Docker नया element था।

addFirst() ने उसे first encounter position पर रखा।

14. addLast() का उपयोग#

addLast() element को last encounter position पर रखता है।

JAVA
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#

TEXT
[Java, SQL, Git]

इस simple case में normal add() और addLast() का visible result समान लग सकता है।

लेकिन addLast() का खास महत्व तब स्पष्ट होता है जब element पहले से set में मौजूद हो।

15. Existing element को addFirst() से reposition करना#

यही behavior सामान्य add() से अलग है।

JAVA
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#

TEXT
[Git, Java, SQL]

Git duplicate के रूप में दूसरी copy नहीं बना।

वही existing element first encounter position पर reposition हुआ।

यानी uniqueness बनी रही।

सिर्फ encounter position बदली।

16. Existing element को addLast() से reposition करना#

JAVA
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#

TEXT
[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 करने देते हैं।

JAVA
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#

TEXT
Java
Git

Java first encounter element है।

Git last encounter element है।

Warning

Empty set पर getFirst() या getLast() call करने पर NoSuchElementException आ सकता है। इसलिए application logic में empty state को ध्यान में रखना चाहिए।

18. First element remove करना#

removeFirst() first encounter element को remove करता है और वही element return करता है।

JAVA
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#

TEXT
Java
[SQL, Git]

19. Last element remove करना#

removeLast() last encounter element remove करता है।

JAVA
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#

TEXT
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

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#

TEXT
[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 में भी दिखाई देता है।

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();

        reverseView.remove("SQL");

        System.out.println(reverseView);
        System.out.println(skills);
    }
}

Expected Output#

TEXT
[Git, Java]
[Java, Git]

SQL reverse view से remove किया गया।

क्योंकि view original set से backed है, SQL original skills set से भी remove हो गया।

इसी प्रकार original set में होने वाले changes reverse view में reflect होते हैं।

Common Mistake

reversed() को copy समझना गलत है। LinkedHashSet के लिए यह original set से जुड़ा reverse-ordered view है।

22. Encounter order को एक flow में समझें#

Visual Diagram80%

Rendering diagram…

यह flow तीन अलग बातें स्पष्ट करता है:

  1. New elements सामान्यतः insertion sequence में आते हैं।
  2. Existing element पर normal add() encounter position नहीं बदलता।
  3. 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 मिलता है।

Key Idea

अगर 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 है।

JAVA
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#

TEXT
[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 बनाया जा सकता है:

JAVA
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#

TEXT
[Java, SQL]

Concurrent iteration जैसी situations में synchronization discipline अलग से महत्वपूर्ण हो सकती है।

इस chapter के लिए मुख्य बात यही याद रखें:

Remember

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 से सबसे महत्वपूर्ण बातें:

  • LinkedHashSet unique elements रखता है।
  • यह predictable encounter order maintain करता है।
  • सामान्य behavior insertion order preserve करता है।
  • यह HashSet को extend करता है।
  • Java 21+ में यह SequencedSet implement करता है।
  • internally hash-based lookup और doubly-linked encounter order का combination होता है।
  • duplicate elements reject होते हैं।
  • एक null element 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, और remove expected O(1) operations हैं।
  • iteration set size के proportional होती है।
  • predictable ordering के बदले HashSet की तुलना में additional overhead आता है।
  • plain LinkedHashSet synchronized नहीं है।
Summary

जब requirement हो "duplicates नहीं चाहिए, लेकिन order predictable रहना चाहिए", तब LinkedHashSet Java Collections Framework की महत्वपूर्ण choices में से एक है।

Interactive learning

Practice lab

Apply this chapter with guided activities, immediate feedback, explanations, and retry.

Practice loads when this section enters view.