Advanced Collections
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 = class का अपना order (compareTo)
- Comparator = custom order (compare)
- Queue = FIFO, TreeMap = auto-sorted keys
Comparable<T> interface implement करके class अपना खुद का "natural order" define करती है — compareTo() method में negative/zero/positive return करके बताते हो कि current object दूसरे से छोटा/बराबर/बड़ा है (convention: negative = "मुझसे छोटा", positive = "मुझसे बड़ा", 0 = "बराबर")।
Collections.sort() या TreeSet automatically इसी order को use करते हैं जब तुम कोई अलग Comparator न दो। एक class का सिर्फ एक natural order हो सकता है (Comparable interface एक ही बार implement होती है) — अगर multiple orderings चाहिए, Comparator use करो।
class Student implements Comparable<Student> {
int marks;
public int compareTo(Student other) {
return this.marks - other.marks; // ascending order by marks
}
}Comparator से class के बाहर से custom ordering दे सकते हो, और एक ही data के लिए multiple different orderings बना सकते हो (जैसे students को कभी marks से sort करो, कभी name से) — बिना Student class को modify किए। Java 8+ में lambda से एक line में लिख सकते हो, और Comparator.comparing() जैसा fluent API भी use कर सकते हो।
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 एक special Queue है जिसमें elements insertion order में नहीं, बल्कि "priority" (natural order या custom Comparator) के हिसाब से निकलते हैं — सबसे छोटा (या जो Comparator define करे) हमेशा सबसे पहले poll() होता है। Internally यह एक "heap" data structure use करती है।
Task scheduling (जैसे सबसे urgent task पहले), Dijkstra's shortest-path algorithm, और "top-K elements" जैसी problems में use होता है।
PriorityQueue<Integer> pq = new PriorityQueue<>();
pq.add(5); pq.add(1); pq.add(3);
System.out.println(pq.poll()); // 1 (sabse chhota pehle)TreeMap और TreeSet दोनों internally Red-Black Tree (self-balancing binary tree) use करते हैं, इसलिए elements/keys हमेशा sorted order में traverse होते हैं, और operations O(log n) समय लेते हैं (HashMap के O(1) से थोड़ा slower, लेकिन sorted order मिलता है free में)।
Extra bonus methods मिलते हैं जो HashMap में नहीं: firstKey(), lastKey(), higherKey(x) (x से बड़ी सबसे छोटी key), floorKey(x) वगैरह — range-based queries के लिए बहुत useful।
Deque (Double-Ended Queue) दोनों तरफ से add/remove कर सकता है — addFirst/addLast, removeFirst/removeLast। इससे Stack (LIFO — push/pop दोनों front से) और Queue (FIFO — offer/poll) दोनों behavior simulate कर सकते हो।
Modern Java में पुरानी Stack class (जो Vector extend करती है, legacy और thread-safe overhead के साथ) की जगह ArrayDeque recommend किया जाता है — faster और cleaner API।
Deque<Integer> stack = new ArrayDeque<>();
stack.push(1); stack.push(2);
System.out.println(stack.pop()); // 2 (LIFO)