Collections Framework · Lesson 72 of 150
Collection Framework
See how the Java Collection Framework fits together, from Iterable and Collection to List, Set, Queue and Map, and learn which one to pick for each job.
Step into a town library and look around. The shelves keep books in a fixed order. The membership register never lists the same card twice. A popular novel has a waiting list, and whoever asked first gets it first. The front desk also has a card index that takes you from a call number straight to a shelf. Four jobs, four different ways of holding things.
Java programs face the same variety, and the Collection Framework is its answer. Instead of writing your own list, set or queue from scratch, you pick a ready-made structure that already fits the job. Here you will see how the framework is organised, what each branch is for, and how to choose between them with confidence.
What is the Collection Framework?
The framework has three layers:
- Interfaces define behaviour: what a list or a set promises to do.
- Implementations are the concrete classes you create with
new. - Algorithms live in the
Collectionshelper class: sorting, searching, shuffling, finding the largest item and more.
All of them are generic, so List<String> holds only strings and the compiler catches mistakes early.
Why is the Collection Framework used?
Before Java 1.2, developers used arrays, Vector and Hashtable, and each had its own method names. Arrays also have a fixed size and almost no built-in methods. The framework fixed both problems.
- Less code to write. Growing, searching, sorting and removing duplicates are already done and well tested.
- One common vocabulary.
add,remove,sizeandcontainsmean the same thing on every collection. - Easy swapping. Code written against
Listworks withArrayListorLinkedList, so changing the class is a one-line edit. - Speed you can predict. Each class has known costs, so you can pick the fast one for your task.
Real-Life Example
Map the library back to Java:
- The shelf where books stand in order, copies allowed, is a
List. You can say "the fifth book on shelf B". - The membership register, where one card number may appear only once, is a
Set. - The waiting list for the new thriller, served first come first served, is a
Queue. - The card index from call number to shelf is a
Map: a key leads to a value.
The first three all "hold books or cards", so they share a parent idea, Collection. The card index is different. It stores pairs, not single items, which is why Map sits in its own family.
Syntax
javaimport java.util.*; List<Type> list = new ArrayList<>(); Set<Type> set = new HashSet<>(); Queue<Type> queue = new ArrayDeque<>(); Map<Key, Val> map = new HashMap<>(); Collections.sort(list); // helper method
import java.util.*;brings in every collection type. In real code, importing each class by name is clearer.- The left side names an interface; the right side picks a class. This habit is called coding to the interface.
<Type>sets the element type, and the empty<>lets Java infer it from the left side.Maptakes two types, one for keys and one for values.Collections(with an s) is a helper class full of static methods.Collectionwithout the s is the interface.
How the Collection Framework Is Organised
Every container except the maps grows from one root. Here is the family tree with the classes you will use most.
textIterable | v Collection | +-- List | +-- ArrayList | +-- LinkedList | +-- Set | +-- HashSet | +-- LinkedHashSet | +-- TreeSet | +-- Queue +-- PriorityQueue +-- Deque +-- ArrayDeque Map (separate family) +-- HashMap +-- LinkedHashMap +-- TreeMap
At the top, Iterable gives every collection an iterator(), which is why a for-each loop works on all of them. Collection adds the shared methods such as add, remove, size, contains and stream. Below it, each sub-interface adds its own promise: List adds positions, Set forbids duplicates and Queue adds ordered removal from the head. LinkedList actually implements both List and Deque. Map does not extend Collection at all, but it can hand you views of its keys, values and entries.
When you are unsure which to use, walk through these questions in order.
textLook up values by a key? yes -> Map no | v Every item must be unique? yes -> Set no | v Serve in arrival or priority order? yes -> Queue no -> List
Once the interface is chosen, pick the class. Use the hash version for speed, the linked version to keep insertion order, and the tree version to keep items sorted.
Example Programs
One library, three collections
javaimport java.util.ArrayDeque; import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.List; import java.util.Queue; import java.util.Set; public class LibraryDesk { public static void main(String[] args) { List<String> loans = new ArrayList<>(); loans.add("Gitanjali"); loans.add("Malgudi Days"); loans.add("Gitanjali"); System.out.println("Loans: " + loans.size()); Set<String> members = new LinkedHashSet<>(); members.add("M101"); members.add("M205"); boolean again = members.add("M101"); System.out.println("M101 added twice? " + again); System.out.println("Members: " + members); Queue<String> waiting = new ArrayDeque<>(); waiting.offer("Rhea"); waiting.offer("Dev"); waiting.offer("Zoya"); System.out.println("Next: " + waiting.poll()); System.out.println("Waiting: " + waiting); } }
Output:
textLoans: 3 M101 added twice? false Members: [M101, M205] Next: Rhea Waiting: [Dev, Zoya]
The list kept both loans of "Gitanjali". The set quietly refused the second "M101" and returned false. The queue handed out the earliest name first.
Coding to the interface
javaimport java.util.ArrayDeque; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.TreeSet; public class ShelfReport { static void report(String label, Collection<String> c) { System.out.println(label + ": " + c.size() + " items, has Ruskin? " + c.contains("Ruskin")); } public static void main(String[] args) { String[] authors = {"Ruskin", "Tagore", "Ruskin"}; report("List", new ArrayList<>(Arrays.asList(authors))); report("Set", new TreeSet<>(Arrays.asList(authors))); report("Queue", new ArrayDeque<>(Arrays.asList(authors))); } }
Output:
textList: 3 items, has Ruskin? true Set: 2 items, has Ruskin? true Queue: 3 items, has Ruskin? true
One method accepts any Collection, so it works with a list, a set and a queue without change. Only the set dropped the repeated author, which shows each class keeping its own rules behind a shared interface.
The Collections helper class
javaimport java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; public class ReturnsDesk { public static void main(String[] args) { List<Integer> daysLate = new ArrayList<>( Arrays.asList(4, 0, 9, 2, 0)); Collections.sort(daysLate); System.out.println("Sorted: " + daysLate); System.out.println("Worst: " + Collections.max(daysLate)); System.out.println("On time: " + Collections.frequency(daysLate, 0)); List<Integer> locked = Collections.unmodifiableList(daysLate); try { locked.add(7); } catch (UnsupportedOperationException e) { System.out.println("Read-only list"); } } }
Output:
textSorted: [0, 0, 2, 4, 9] Worst: 9 On time: 2 Read-only list
Collections sorted the list, found the largest value and counted zeros without a single loop in our code. unmodifiableList gives out a read-only view, which is handy when other code should look but not touch.
List vs Set vs Queue vs Map
| Point | List | Set | Queue | Map |
|---|---|---|---|---|
| Stores | Items | Items | Items | Key-value pairs |
| Duplicates | Allowed | Not allowed | Allowed | Keys unique |
| Order | By index | Depends on class | Head first | Depends on class |
| Main access | get(i) | contains | poll() | get(key) |
| Common class | ArrayList | HashSet | ArrayDeque | HashMap |
| Library match | Shelf | Register | Waiting list | Card index |
Common Mistakes
- Thinking `Map` is a `Collection`. It is not, so a
Mapcannot be passed where aCollectionis expected. UsekeySet()orvalues()instead. - Picking a list for uniqueness. Calling
containsbefore everyaddon a big list is O(n) each time. ASetdoes the check for you. - Declaring the class type everywhere. Writing
ArrayList<String>in method parameters locks callers to one class. PreferList<String>. - Using legacy classes.
Vector,StackandHashtablestill work but are slower. UseArrayList,ArrayDequeandHashMap.
Interview Questions
What is the root interface of the Collection Framework?
Ans:Collection is the root for lists, sets and queues, and it extends Iterable, which provides the iterator used by for-each loops. Map has its own separate hierarchy.
Why does Map not extend Collection?
Ans:A collection holds single items, but a map holds key-value pairs, so methods like add(item) do not fit. Instead, a map offers keySet(), values() and entrySet() views that are collections.
What is the difference between Collection and Collections?
Ans:Collection is an interface that containers implement. Collections is a utility class of static methods such as sort, reverse, max and unmodifiableList.
How do you choose between List, Set and Queue?
Ans:Use a List when position and duplicates matter, a Set when every item must be unique, and a Queue when items are processed in arrival or priority order.
What does coding to the interface mean for collections?
Ans:It means declaring variables and parameters with interface types like List and creating them with a class like ArrayList. The rest of the code then works unchanged if you later switch the class.
Summary
- The framework lives in
java.utiland has interfaces, implementations and algorithms. Iterable→Collection→List,SetandQueueform one family;Mapstands apart.- Lists keep order and duplicates, sets keep unique items, queues serve from the head.
- Maps link unique keys to values.
- Hash classes are fastest, linked classes keep insertion order, tree classes keep items sorted.
Collectionsoffers ready-made helpers such assort,maxandfrequency.
Related Topics
Practice Problems
Try each problem on your own first, then compare with the solution.
Easy: Distinct Genres at the Returns Desk
Today's returned books had these genres: Poetry, Mystery, Poetry, History, Mystery, Travel. Print the distinct genres twice: once in the order they first appeared, and once in alphabetical order. Use the right Set class for each.
Expected output:
textFirst seen: [Poetry, Mystery, History, Travel] Sorted: [History, Mystery, Poetry, Travel]
Show answerHide answer
Set, so both remove repeats. They differ only in the order they promise, which is exactly the choice the framework lets you make.javaimport java.util.Arrays; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import java.util.TreeSet; public class GenreDesk { public static void main(String[] args) { List<String> returned = Arrays.asList("Poetry", "Mystery", "Poetry", "History", "Mystery", "Travel"); Set<String> firstSeen = new LinkedHashSet<>(returned); Set<String> sorted = new TreeSet<>(returned); System.out.println("First seen:"); System.out.println(firstSeen); System.out.println("Sorted:"); System.out.println(sorted); } }
Output:
textFirst seen: [Poetry, Mystery, History, Travel] Sorted: [History, Mystery, Poetry, Travel]
Medium: Books Grouped by Author
The catalogue has these entries, each written as author:title: Tagore:Gora, Premchand:Godaan, Tagore:Chokher Bali, Narayan:Swami, Premchand:Nirmala. Build a Map from each author to a List of their titles. Print the authors in alphabetical order, each with their titles in catalogue order.
Expected output:
textNarayan -> [Swami] Premchand -> [Godaan, Nirmala] Tagore -> [Gora, Chokher Bali]
Show answerHide answer
javaimport java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.TreeMap; public class AuthorIndex { public static void main(String[] args) { String[] catalogue = {"Tagore:Gora", "Premchand:Godaan", "Tagore:Chokher Bali", "Narayan:Swami", "Premchand:Nirmala"}; Map<String, List<String>> byAuthor = new TreeMap<>(); for (String entry : catalogue) { String[] parts = entry.split(":"); byAuthor.computeIfAbsent(parts[0], k -> new ArrayList<>()).add(parts[1]); } for (Map.Entry<String, List<String>> e : byAuthor.entrySet()) { System.out.println(e.getKey() + " -> " + e.getValue()); } } }
Output:
textNarayan -> [Swami] Premchand -> [Godaan, Nirmala] Tagore -> [Gora, Chokher Bali]