Master Java Collections: Lists, Sets, Queues, Maps & Their Core Implementations
This article provides a comprehensive overview of Java's collection framework, explaining the differences between List, Set, Queue, and Map, detailing their underlying data structures, and offering best practices for safe traversal and modification.
#Java Collections Overview
Java collections, also called containers, are derived from two main interfaces: Collection for single elements and Map for key‑value pairs. Collection has three primary sub‑interfaces: List, Set, and Queue.
Java collection framework diagram:
Note: the diagram shows only major inheritance relationships; many abstract classes and helper classes are omitted.
# Differences among List, Set, Queue, Map
List: ordered, allows duplicates.
Set: unordered, no duplicates.
Queue: ordered according to a specific rule, allows duplicates.
Map: stores key‑value pairs; keys are unordered and unique, values are unordered and may duplicate.
# Underlying data structures of the collection framework
Below are the concrete classes for each interface.
# List
ArrayList – backed by an Object[] array.
Vector – backed by an Object[] array.
LinkedList – doubly linked list (circular list before JDK 1.7).
# Set
HashSet – implements Set using a HashMap.
LinkedHashSet – subclass of HashSet, maintains insertion order via a LinkedHashMap.
TreeSet – uses a red‑black tree to provide ordered, unique elements.
# Queue
PriorityQueue – implements a binary heap using an Object[] array.
ArrayQueue – uses an Object[] array with two pointers.
# Map
HashMap – before JDK 1.8 a bucket is an array plus linked list; after JDK 1.8 long chains are transformed into red‑black trees.
LinkedHashMap – extends HashMap and adds a doubly linked list to preserve insertion order.
Hashtable – array plus linked list for collision handling.
TreeMap – red‑black tree implementation.
Collection Traversal Tips
According to the Alibaba Java Development Manual, do not perform remove/add operations inside a foreach loop. Use an Iterator’s remove method, and lock the Iterator when concurrent modifications are possible.
Although foreach is syntactic sugar for an Iterator, calling collection.remove/add directly bypasses the Iterator’s remove/add, causing the Iterator to detect unexpected modifications and throw a ConcurrentModificationException (fail‑fast behavior).
Fail‑fast collections throw ConcurrentModificationException when modified during iteration, even in single‑threaded contexts.
Since Java 8, you can use Collection#removeIf() to delete elements that match a predicate, e.g.:
List<Integer> list = new ArrayList<>();
for (int i = 1; i <= 10; ++i) {
list.add(i);
}
list.removeIf(filter -> filter % 2 == 0); // delete all even numbers
System.out.println(list); // [1, 3, 5, 7, 9]Other traversal options include using a classic for loop or employing fail‑safe collections from java.util.concurrent, which do not throw ConcurrentModificationException.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Java Interview Crash Guide
Dedicated to sharing Java interview Q&A; follow and reply "java" to receive a free premium Java interview guide.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
