Java · Data Structures · APIs

Java Collections Framework

The Java Collections Framework provides standard interfaces and implementations for storing, retrieving, iterating, sorting, and organizing groups of objects.

What is a Collection?

A collection is an object that groups multiple elements together. Java provides standard interfaces so algorithms can work with groups of data without depending on one concrete implementation.

Important distinction: Map is part of the Java Collections Framework, but it does not extend the Collection interface.

Main Interfaces

InterfaceMain propertyDuplicates?Typical use
ListOrdered, index-based sequenceYesShopping list, ordered records
SetUnique elementsNoTags, unique IDs, membership tests
QueueElements processed in an orderUsually yesTasks, requests, scheduling
DequeInsert/remove at both endsUsually yesStacks, queues, sliding windows
MapKey-value associationsKeys: noIndexes, dictionaries, lookup tables

Common Implementations

  • ArrayList: dynamic array; fast indexed access and usually the default choice for a list.
  • LinkedList: doubly linked list; also implements Deque. It can add/remove efficiently at known positions such as the ends, but indexed access is slow.
  • HashSet: hash-based set with fast average-case membership operations and no guaranteed iteration order.
  • LinkedHashSet: preserves insertion order while enforcing uniqueness.
  • TreeSet: sorted set based on a tree structure.
  • HashMap: hash-based key-value map with fast average-case lookup.
  • LinkedHashMap: preserves a predictable encounter order.
  • TreeMap: sorted map ordered by keys.
  • PriorityQueue: retrieves elements according to priority rather than insertion order.
  • ArrayDeque: efficient general-purpose stack and queue implementation.

Which One Should You Use?

NeedGood first choiceReason
Indexed ordered dataArrayListFast random access, compact storage
Unique unordered valuesHashSetFast average lookup
Unique sorted valuesTreeSetMaintains sort order
Key-value lookupHashMapFast average key lookup
Sorted keysTreeMapKeys remain ordered
FIFO queueArrayDequeEfficient operations at both ends
Priority-based processingPriorityQueueRetrieves highest/lowest priority according to ordering

Basic Examples

List<String> shoppingList = new ArrayList<>();
shoppingList.add("Milk");
shoppingList.add("Bread");
shoppingList.add("Milk"); // duplicate allowed

Set<String> hobbies = new HashSet<>();
hobbies.add("Reading");
hobbies.add("Swimming");
hobbies.add("Reading");   // duplicate ignored

Map<String, String> contacts = new HashMap<>();
contacts.put("Alice", "12345");
contacts.put("Bob", "67890");

Queue<String> bankLine = new ArrayDeque<>();
bankLine.offer("Customer1");
bankLine.offer("Customer2");
System.out.println(bankLine.poll()); // Customer1

Iterating Through Collections

for (String name : shoppingList) {
    System.out.println(name);
}

You can also use an explicit iterator:

Iterator<String> it = shoppingList.iterator();

while (it.hasNext()) {
    String item = it.next();
    System.out.println(item);
}

Sorting

List<String> names =
    new ArrayList<>(List.of("Charlie", "Alice", "Bob"));

Collections.sort(names);

Modern Java also supports comparator-based sorting:

names.sort(Comparator.reverseOrder());

Natural Ordering vs Comparator

  • Comparable<T> defines a type's natural order using compareTo.
  • Comparator<T> defines an external or alternative ordering using compare.

Immutability and Factory Methods

List<String> fixed = List.of("A", "B", "C");
Set<Integer> numbers = Set.of(1, 2, 3);
Map<String, Integer> scores =
    Map.of("Alice", 90, "Bob", 85);

These factory methods create unmodifiable collections. Attempts to add or remove elements cause an exception.

Useful Complexity Intuition

StructureTypical strengthTypical trade-off
ArrayListFast indexed accessMiddle insert/remove may shift elements
LinkedListFast end operations when used as dequeSlow indexed access
HashSet / HashMapFast average lookupNo sorted order
TreeSet / TreeMapSorted dataUsually slower than hashing for pure lookup
PriorityQueueFast access to priority elementNot a fully sorted iteration

Common Mistakes

  • Assuming HashMap or HashSet preserves insertion order.
  • Using LinkedList for frequent indexed access.
  • Modifying a collection during enhanced-for iteration without using the iterator correctly.
  • Forgetting that mutable objects used as hash keys must have consistent equals and hashCode.

Conclusion

The Java Collections Framework gives you interchangeable data-structure interfaces with specialized implementations. Choose according to ordering, uniqueness, lookup, indexing, queue behavior, sorting, and mutation requirements rather than choosing a class only by familiarity.