Java Collections Framework
Introduced in 2026-02-26-java-basics-part-02-collections-and-strings (Lecture 1, Week 1) — see that lecture for the worked push/pop/add/remove traces. All of these live in java.util.*, and (unlike arrays) grow/shrink automatically.
Why collections instead of arrays?
Arrays have a fixed size at creation and don’t automatically close gaps when an element is removed from the middle. Collections solve both problems, at the cost of only being able to store objects (reference types) — see java-primitive-and-reference-types for the primitive wrapper classes (Integer, Double, etc.) used to store primitives inside them.
Stack — LIFO
| Method | Description |
|---|---|
empty() |
Is this stack empty? |
peek() |
Return the object at the top of the stack |
pop() |
Remove (and return) the object at the top of the stack |
push(obj) |
Put obj on the top of the stack |
Stack<Type> stacks = new Stack<>();pop() on an empty stack throws EmptyStackException.
List
An interface, not a particular implementation — you can declare a variable as List, but can’t do new List().
ArrayList— better for random access (get(i)).LinkedList— better for operations that modify the middle of the list.
Holds items in sequential order (like an array), 0-indexed, with no fixed size limit; supports inserting/removing at any position.
Set
Stores unique items (no duplicates); don’t assume any iteration order.
interface Set<E> {
int size();
boolean contains(E item);
boolean add(E e);
boolean remove(E item);
}TreeSet<E>—Emust implementComparable(e.g.String).HashSet<E>—Emust have sensiblehashCode()/equals().
Map
Stores key → value pairs (like a Python dict) — specify a type for both the key and the value, e.g. Map<Integer, String>.
interface Map<K, V> {
int size();
boolean containsKey(K key);
boolean containsValue(V value);
V get(K key);
V put(K key, V value);
V remove(K key);
Set<K> keySet();
}TreeMap<K,V>—Kmust implementComparable.HashMap<K,V>—Kmust have sensiblehashCode()/equals().
The hashCode/equals contract
HashSet/HashMap rely on their elements/keys satisfying:
x.equals(y)\(\iff\)y.equals(x)(symmetric).x.equals(y)\(\implies\)x.hashCode() == y.hashCode().
hashCode() returns an integer generated by a hashing algorithm for the object — two objects that are .equals() must hash the same, or a HashSet/HashMap won’t be able to find them correctly.