📊
Collections

Advanced Collections

Comparator, Queue & TreeMap
💡 Comparable एक चीज़ ख़ुद बताती है "मैं कैसे sort होती हूँ" (जैसे एक line में खड़े बच्चों की height built-in होती है)। Comparator एक बाहर का teacher है जो custom order decide करता है। Queue एक line जैसी है (पहले आओ, पहले जाओ)।

Comparable (compareTo method) class के अंदर define होता है — "natural ordering" बताता है। Comparator (compare method) बाहर से custom ordering देता है, जितनी चाहो उतनी बनाओ।

Queue FIFO (First-In-First-Out) order follow करता है — जैसे ticket line। Deque दोनों तरफ़ से add/remove कर सकता है।

TreeMap/TreeSet अपने आप keys को sorted order में रखते हैं (HashMap/HashSet के उलट, जहाँ order guaranteed नहीं होता)।

List<String> names = new ArrayList<>(List.of("Zoya","Aman","Ravi"));
names.sort(Comparator.naturalOrder());
// [Aman, Ravi, Zoya]

Queue<Integer> q = new LinkedList<>();
q.add(1); q.add(2);
System.out.println(q.poll()); // 1
📊
Comparable एक चीज़ ख़ुद बताती है "मैं कैसे sort होती हूँ" (जैसे एक line में खड़े बच्चों की height built-in होती है)। Comparator एक बाहर का teacher है जो custom order decide करता है। Queue एक line जैसी है (पहले आओ, पहले जाओ)।
1 / 5
इस page में (5 subtopics)

Comparable<T> interface implement karke class apna khud ka "natural order" define karti hai — compareTo() method mein negative/zero/positive return karke batate ho ki current object doosre se chhota/barabar/bada hai (convention: negative = "mujhse chhota", positive = "mujhse bada", 0 = "barabar").

Collections.sort() ya TreeSet automatically isi order ko use karte hain jab tum koi alag Comparator na do. Ek class ka sirf EK natural order ho sakta hai (Comparable interface ek hi baar implement hoti hai) — agar multiple orderings chahiye, Comparator use karo.

class Student implements Comparable<Student> {
  int marks;
  public int compareTo(Student other) {
    return this.marks - other.marks; // ascending order by marks
  }
}
⚠️Common Mistake: this.marks - other.marks integer overflow risk rakhta hai agar marks bahut bade/negative numbers hon (edge case). Safer: Integer.compare(this.marks, other.marks) use karo.

Comparator se class ke bahar se custom ordering de sakte ho, aur ek hi data ke liye multiple different orderings bana sakte ho (jaise students ko kabhi marks se sort karo, kabhi name se) — bina Student class ko modify kiye. Java 8+ mein lambda se ek line mein likh sakte ho, aur Comparator.comparing() jaisa fluent API bhi use kar sakte ho.

List<Student> students = getStudents();
students.sort((a, b) -> b.marks - a.marks); // descending
students.sort(Comparator.comparing(s -> s.name)); // by name
students.sort(Comparator.comparing((Student s) -> s.marks).reversed());

PriorityQueue ek special Queue hai jisme elements insertion order mein nahi, balki "priority" (natural order ya custom Comparator) ke hisaab se nikalte hain — sabse chhota (ya jo Comparator define kare) hamesha sabse pehle poll() hota hai. Internally ye ek "heap" data structure use karti hai.

Task scheduling (jaise sabse urgent task pehle), Dijkstra's shortest-path algorithm, aur "top-K elements" jaisi problems mein use hota hai.

PriorityQueue<Integer> pq = new PriorityQueue<>();
pq.add(5); pq.add(1); pq.add(3);
System.out.println(pq.poll()); // 1 (sabse chhota pehle)

TreeMap aur TreeSet dono internally Red-Black Tree (self-balancing binary tree) use karte hain, isliye elements/keys hamesha sorted order mein traverse hote hain, aur operations O(log n) time lete hain (HashMap ke O(1) se thoda slower, lekin sorted order milta hai free mein).

Extra bonus methods milte hain jo HashMap mein nahi: firstKey(), lastKey(), higherKey(x) (x se badi sabse chhoti key), floorKey(x) waghera — range-based queries ke liye bahut useful.

Deque (Double-Ended Queue) dono taraf se add/remove kar sakta hai — addFirst/addLast, removeFirst/removeLast. Isse Stack (LIFO — push/pop dono front se) aur Queue (FIFO — offer/poll) dono behavior simulate kar sakte ho.

Modern Java mein purani Stack class (jo Vector extend karti hai, legacy aur thread-safe overhead ke saath) ki jagah ArrayDeque recommend kiya jaata hai — faster aur cleaner API.

Deque<Integer> stack = new ArrayDeque<>();
stack.push(1); stack.push(2);
System.out.println(stack.pop()); // 2 (LIFO)