🧺
Collections

Collections: List, Set, Map

Storing Groups of Data
💡 ArrayList is a train with its compartments in order (accessed by index). HashSet is a sticker album where no sticker repeats. HashMap is a locker room where every locker has its own name-tag (key).

ArrayList is an ordered list, duplicates allowed, accessed by index.

HashSet holds only unique values, no order guaranteed. HashMap stores key-value pairs — you can find a value instantly by its key, like a locker by name.

List<String> names = new ArrayList<>();
Set<Integer> ids = new HashSet<>();
Map<String, Integer> ages = new HashMap<>();
ages.put("Aarav", 10);
🧺
ArrayList is a train with its compartments in order (accessed by index). HashSet is a sticker album where no sticker repeats. HashMap is a locker room where every locker has its own name-tag (key).
1 / 5
⚡ Quick Recap
  • List = ordered, duplicates OK
  • Set = unique values only
  • Map = key-value pairs
On this page (5 subtopics)

At the very top is the "Collection" interface, which List, Set, and Queue extend. Map is NOT part of this hierarchy (since it stores key-value pairs, not single elements) — it's its own separate interface (Map<K,V>) that doesn't extend Collection.

Each type solves a different problem: List allows order + duplicates (like a shopping list — order matters and the same item can appear twice). Set only guarantees uniqueness (like roll numbers in a class — no repeats possible). Queue defines a processing order (like a ticket line — first come, first served). Map gives fast key-based lookup (like a phonebook — find the number by name).

💡Tip: Interviews often ask "Collection vs Collections" — Collection (singular) is an interface (the parent of List/Set/Queue), Collections (plural) is a utility class full of static helper methods (Collections.sort(), Collections.reverse(), etc.).

ArrayList is the most commonly used implementation of the List interface — internally it's a resizable array. add() adds an element (at the end by default, or a specific index), get(index) retrieves one (O(1) — very fast, like direct array access), remove() removes by index or value, size() tells you how many elements there are.

contains() checks if a value exists (O(n) — a linear search, since ArrayList has no idea where to look), isEmpty() tells you if it's empty, indexOf() finds a value's position.

List<String> names = new ArrayList<>();
names.add("Aarav");
names.add("Riya");
System.out.println(names.get(0));   // Aarav
System.out.println(names.contains("Riya")); // true
names.remove("Aarav");
⚠️Common Mistake: ArrayList.contains() or indexOf() take O(n) time (they scan the whole list) — if you're repeatedly checking "does this value exist" on a large dataset, a HashSet will be much faster (O(1) average).

HashSet is the fastest (add/remove/contains all average O(1)) but gives no order guarantee (hash-based storage, elements appear in "random" order when printed). Most of the time this is the best choice when order doesn't matter.

LinkedHashSet maintains insertion order (iterates in the same order things were added) — a bit slower than HashSet (extra linked-list overhead), but choose this when you need predictable order.

TreeSet always keeps elements in sorted (natural or a custom Comparator's) order — internally it uses a balanced tree (Red-Black Tree), so operations take O(log n) time (slower than HashSet, but you get sorted order automatically).

HashSetLinkedHashSetTreeSet
OrderNo guaranteeInsertion orderSorted order
Speed (add/contains)O(1) averageO(1) averageO(log n)
When to useJust need uniquenessUniqueness + insertion orderUniqueness + sorted

HashMap calculates every key's hashCode(), and decides where to store the value based on that hash (a "bucket" — internally there's an array of buckets). This is exactly why looking up a value by key is average O(1) (very fast) — like a direct array-index jump, not a linear search.

If two keys' hashes end up the same ("collision"), they're stored together in the same bucket as a linked list (or, in Java 8+, a balanced tree if there are way too many collisions) — the worst case can be a bit slower, but with a good hashCode() implementation this is rare.

HashMap allows a null key (only one), and multiple null values. This is different from Hashtable (an older, legacy class), which doesn't allow any null at all.

Need order + duplicates OK → ArrayList. Just unique values, order doesn't matter → HashSet. Unique + need insertion order → LinkedHashSet. Unique + need sorted → TreeSet. Need fast lookup by key → HashMap. Need lookup by key + sorted keys → TreeMap.

NeedBest Choice
Ordered list, duplicates OKArrayList
Frequent insert/delete in the middleLinkedList
Only unique valuesHashSet
Unique + insertion orderLinkedHashSet
Unique + sortedTreeSet
Key-value, fast lookupHashMap
Key-value, sorted keysTreeMap
FIFO processingLinkedList (as Queue) / ArrayDeque