Java Collections and Data Structures
Introduction
Collections and Data Structures are the backbone of programming in Java. They provide efficient ways to store, organize, and manipulate data.
Java offers a rich Collections Framework that includes interfaces, classes, and algorithms for handling groups of objects.
Beyond collections, understanding fundamental data structures like stacks, queues, trees, and graphs is essential for interviews and real-world applications.
Java Collections Framework Overview
The Java Collections Framework (JCF) is a unified architecture for representing and manipulating collections. It includes:
- Interfaces: List, Set, Map, Queue, Deque.
- Implementations: ArrayList, LinkedList, HashSet, TreeSet, HashMap, TreeMap, PriorityQueue, etc.
- Algorithms: Sorting, searching, shuffling, reversing.
List
A List is an ordered collection that allows duplicates. It provides positional access and iteration.
// Example: ArrayList
List<String> list = new ArrayList<>();
list.add("Apple");
list.add("Banana");
list.add("Apple"); // duplicates allowed
System.out.println(list);
Interview Tip: Use ArrayList for fast random access, LinkedList for frequent insertions/deletions.
Set
A Set is an unordered collection that does not allow duplicates.
// Example: HashSet
Set<String> set = new HashSet<>();
set.add("Apple");
set.add("Banana");
set.add("Apple"); // ignored
System.out.println(set);
Interview Tip: Use HashSet for fast lookups, TreeSet for sorted order.
Map
A Map stores key-value pairs. Keys are unique, values can be duplicated.
// Example: HashMap
Map<Integer, String> map = new HashMap<>();
map.put(1, "Alice");
map.put(2, "Bob");
map.put(1, "Charlie"); // overwrites
System.out.println(map);
Interview Tip: Use HashMap for fast access, TreeMap for sorted keys, LinkedHashMap for insertion order.
Queue
A Queue is a collection designed for holding elements prior to processing, typically in FIFO order.
// Example: Queue
Queue<String> queue = new LinkedList<>();
queue.add("Task1");
queue.add("Task2");
System.out.println(queue.poll()); // removes Task1
Deque
A Deque (double-ended queue) allows insertion and removal from both ends.
// Example: Deque
Deque<String> deque = new ArrayDeque<>();
deque.addFirst("First");
deque.addLast("Last");
System.out.println(deque);
Stack
A Stack is a LIFO (Last-In-First-Out) data structure.
// Example: Stack
Stack<Integer> stack = new Stack<>();
stack.push(10);
stack.push(20);
System.out.println(stack.pop()); // removes 20
PriorityQueue
A PriorityQueue orders elements based on their natural ordering or a comparator.
// Example: PriorityQueue
PriorityQueue<Integer> pq = new PriorityQueue<>();
pq.add(30);
pq.add(10);
pq.add(20);
System.out.println(pq.poll()); // 10
Tree Data Structures
Trees are hierarchical structures. In Java, TreeSet and TreeMap are based on Red-Black Trees.
// Example: TreeMap
TreeMap<Integer, String> treeMap = new TreeMap<>();
treeMap.put(2, "B");
treeMap.put(1, "A");
treeMap.put(3, "C");
System.out.println(treeMap); // sorted by key
Graph Data Structures
Graphs represent relationships between entities. Java does not have a built-in graph, but you can implement using adjacency lists or matrices.
// Example: Graph using adjacency list
class Graph {
Map<Integer, List<Integer>> adj = new HashMap<>();
void addEdge(int u, int v) {
adj.computeIfAbsent(u, k -> new ArrayList<>()).add(v);
}
}
Algorithms in Collections
The Collections class provides static methods for algorithms:
List<Integer> nums = Arrays.asList(3, 1, 2);
Collections.sort(nums);
Collections.reverse(nums);
Collections.shuffle(nums);
Interview-Ready Notes
- List vs Set: List allows duplicates, Set does not.
- HashMap vs TreeMap: HashMap is faster, TreeMap maintains sorted order.
- Queue vs Stack: Queue is FIFO, Stack is LIFO.
- PriorityQueue: Useful for scheduling tasks based on priority.
- Tree vs Graph: Trees are hierarchical, graphs are network-based.
Best Practices
- Choose the right collection based on requirements (ordering, duplicates, performance).
- Always override
equals()andhashCode()when using custom objects in collections. - Prefer
ArrayListfor random access andLinkedListfor frequent insertions/deletions. - Use
HashSetwhen uniqueness matters andTreeSetwhen sorted order is required. - Leverage
HashMapfor fast lookups,LinkedHashMapfor predictable iteration order, andTreeMapfor sorted keys. - For thread-safe operations, use concurrent collections like
ConcurrentHashMaporCopyOnWriteArrayList. - When working with queues, choose
PriorityQueuefor priority-based scheduling andArrayDequefor double-ended operations. - Use immutable collections (via
Collections.unmodifiableList()or Java 9+ factory methods) when you want to prevent accidental modifications. - Document the expected behavior of collections in APIs to avoid misuse.
- Be mindful of memory usage β large collections can consume significant heap space.
Conclusion
Collections and Data Structures form the foundation of efficient programming in Java. The Collections Framework provides ready-to-use implementations for common needs like lists, sets, maps, and queues, while fundamental data structures like stacks, trees, and graphs help solve complex problems.
For interviews, itβs important not only to know the syntax but also to understand the trade-offs between different collections. For example, choosing HashMap vs TreeMap depends on whether you need speed or sorted order. Similarly, deciding between ArrayList and LinkedList depends on whether random access or frequent insertions are more important.
By mastering collections and data structures, you gain the ability to design scalable, maintainable, and high-performance applications. This knowledge is highly valued in interviews, where questions often test both theoretical understanding and practical application.
Interview-Ready Summary
- List: Ordered, allows duplicates. Use
ArrayListorLinkedList. - Set: Unordered, no duplicates. Use
HashSetorTreeSet. - Map: Key-value pairs. Use
HashMap,TreeMap, orLinkedHashMap. - Queue: FIFO. Use
LinkedListorPriorityQueue. - Deque: Double-ended queue. Use
ArrayDeque. - Stack: LIFO. Use
StackorDeque. - Trees: Hierarchical, used in
TreeSetandTreeMap. - Graphs: Network-based, implemented via adjacency lists or matrices.
In interviews, always connect your answer to real-world scenarios. For example: βIβd use a HashMap to store user sessions for fast retrieval, but a TreeMap if I need to maintain sessions in sorted order by timestamp.β