List Interface
The List interface is a core component of the Java Collections Framework, extending the Collection enterface. It defines operations for ordered collections of elements.
Key Characteristics
- Order Preservation: Elements are stored and retrieved in the sequence they were added.
- Duplicate Elements: Allows multiple identical elements.
- Dynamic Sizing: The capacity automatically adjusts as elements are added or removed.
Essential Operations
appendElement(E item): Adds an item to the end of the list.insertAtPosition(int pos, E item): Inserts an item at the specified index.deleteByIndex(int pos): Removes and returns the element at the given position.deleteByObject(Object obj): Removes the first occurrence of the specified object.fetchElement(int pos): Retrieves the element at the specified index.replaceElement(int pos, E item): Substitutes the element at the given position with a new item.findFirstIndex(Object obj): Returns the index of the first occurrence of the object.findLastIndex(Object obj): Returns the index of the last occurrence of the object.getCount(): Returns the total number of elements.isListEmpty(): Returnstrueif the list contains no elements.
Primary Implementations
ArrayList
- Implements a resizable array.
- Provides fast random access via indices.
- Insertion and deletion in the middle can be inefficient due to element shifting.
LinkedList
- Implements a doubly-linked list.
- Efficient for frequent insertions and deletions, especially at the ends.
- Random access is slower compared to
ArrayList.
Vector (Legacy)
- A synchronized, thread-safe version similar to
ArrayList. - Generally not recommended due to performance overhead;
ArrayListwith external synchronization is preferred.
Stack (Legacy)
- Extends
Vectorto provide Last-In-First-Out (LIFO) stack operations.
CopyOnWriteArrayList
- A thread-safe variant where modifications create a copy of the underlying array.
- Suitable for scenarios with many read operations and infrequent writes.
Set Interface
The Set interface represents a collection that contains no duplicate elements. It models the mathematical set abstraction.
Key Characteristics
- Uniqueness: Guarantees that no two elements are equal (as determined by
equals()). - No Guaranteed Order: Does not inherently maintain insertion order, though some implementations do.
Essential Operations
includeElement(E item): Adds the element if not already present; returnsfalseif the element exists.excludeElement(Object obj): Removes the specified object from the set.hasElement(Object obj): Returnstrueif the set contains the object.elementCount(): Returns the number of elements.isSetEmpty(): Returnstrueif the set contains no elements.
Primary Implementations
HashSet
- Backed by a hash table (essentially a
HashMap). - Offers constant-time performance for basic operations, assuming a good hash function.
- Does not maintain any order.
LinkedHashSet
- Extends
HashSetand maintains a doubly-linked list running through all entries. - Preserves the insertion order of elements.
TreeSet
- Implements a navigable set using a Red-Black tree.
- Stores elements in sorted order (natural ordering or via a provided
Comparator).
CopyOnWriteArraySet
- A thread-safe set backed by a copy-on-write array.
- Optimized for read-heavy, write-rarely concurrent scenarios.
Example Usage
Set<String> fruitBasket = new HashSet<>();
fruitBasket.add("Apple");
fruitBasket.add("Banana");
fruitBasket.add("Cherry");
if (fruitBasket.contains("Apple")) {
System.out.println("Apple is in the basket.");
}
fruitBasket.remove("Banana");
System.out.println("Basket size: " + fruitBasket.size());
Queue Interface
The Queue interface defines a collection designed for holding elements prior to processing, typically following a First-In-First-Out (FIFO) discipline.
Key Characteristics
- Processing Order: Standard queues are FIFO, but other orderings (e.g., priority-based) are possible.
- Capacity: May be bounded (fixed capacity) or unbounded.
- Blocking Behavior: Some implementations support operations that wait for the queue to become non-empty when retrieving or non-full when storing.
Essential Operations
enqueue(E item)/offer(E item): Inserts an element.offerreturnsfalseon failure in bounded queues.dequeue()/poll(): Retrieves and removes the head element.pollreturnsnullif the queue is empty.inspectHead()/peek(): Retrieves, but does not remove, the head element.peekreturnsnullif empty.queueSize(): Returns the number of elements.
Primary Implementations
LinkedList: Can function as a FIFO queue due to its efficient insertion/deletion at both ends.PriorityQueue: Orders elements according to their natural ordering or a specified comparator.ArrayDeque: A resizable-array implementation of a double-ended queue, usable as a stack or queue.- Blocking Queues (in
java.util.concurrent):LinkedBlockingQueue: Optional bounded FIFO queue.ArrayBlockingQueue: Bounded FIFO queue backed by an array.SynchronousQueue: A queue where each insert must wait for a corresponding remove.DelayQueue: Holds elements until a specified delay has elapsed.
Example Usage
Queue<String> taskQueue = new LinkedList<>();
taskQueue.offer("Task A");
taskQueue.offer("Task B");
String currentTask = taskQueue.poll(); // Retrieves and removes "Task A"
System.out.println("Processing: " + currentTask);
String nextTask = taskQueue.peek(); // Retrieves "Task B" without removal
System.out.println("Next task: " + nextTask);
Non-Blocking Queues
Non-blocking queues allow thread-safe access with out using locks, enabling high-throughput in concurrent applications.
Key Characteristics
- Lock-Free: Utilize atomic operations (like Compare-And-Swap) for synchronization.
- High Concurrency: Multiple threads can operate on the queue simultaneously without blocking.
- No Capacity Guarantees: Often unbounded, though some may have limitations.
Java Implementations
ConcurrentLinkedQueue: An unbounded, thread-safe FIFO queue based on linked nodes.ConcurrentLinkedDeque: An unbounded, thread-safe double-ended queue.
Example Usage
import java.util.concurrent.ConcurrentLinkedQueue;
public class ConcurrentProcessor {
private final ConcurrentLinkedQueue<DataItem> workQueue = new ConcurrentLinkedQueue<>();
public void submitTask(DataItem item) {
workQueue.offer(item); // Non-blocking add
}
public void processTasks() {
DataItem item;
while ((item = workQueue.poll()) != null) { // Non-blocking remove
handleItem(item);
}
}
private void handleItem(DataItem item) { /* ... */ }
}
Blocking Queues
Blocking queues support operations that wait for the queue to become non-empty when taking an element, or non-full when putting an element. They are fundamental for producer-consumer patterns.
Key Characteristics
- Thread Coordination: Naturally synchronize producer and consumer threads.
- Bounded Capacity: Most have a fixed capacity limit.
- Blocking Operations: Methods like
put()andtake()will block the calling thread until the operation can succeed.
Essential Operations
blockingPut(E item): Inserts the element, waiting if necessary for space to become available.blockingTake(): Retrieves and removes the head, waiting if necessary for an element to become available.timedOffer(E item, long timeout, TimeUnit unit): Inserts the element, waiting up to the specified time for space.timedPoll(long timeout, TimeUnit unit): Retrieves and removes the head, waiting up to the specified time.availableCapacity(): Returns the number of additional elements the queue can accept.
Primary Implementations
ArrayBlockingQueue: A bounded FIFO queue backed by an array.LinkedBlockingQueue: An optionally bounded FIFO queue based on linked nodes.PriorityBlockingQueue: An unbounded blocking queue that orders elements by priority.SynchronousQueue: A queue where each insert must wait for a corresponding remove by another thread.DelayQueue: An unbounded queue of delayed elements, where an element can only be taken when its delay has expired.
Example Usage
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class ProducerConsumer {
private static final int MAX_QUEUE_CAPACITY = 5;
private final BlockingQueue<Integer> sharedBuffer = new ArrayBlockingQueue<>(MAX_QUEUE_CAPACITY);
public void produceItems() throws InterruptedException {
for (int i = 0; i < 10; i++) {
sharedBuffer.put(i); // Blocks if queue is full
System.out.println("Produced: " + i);
}
}
public void consumeItems() throws InterruptedException {
for (int i = 0; i < 10; i++) {
int item = sharedBuffer.take(); // Blocks if queue is empty
System.out.println("Consumed: " + item);
}
}
}
Map Interface
The Map interface stores key-value pairs (entries), allowing efficient retrieval of a value based on its associated key.
Key Characteristics
- Key-Value Association: Maps a unique key to a specific value.
- Key Uniqueness: No duplicate keys allowed; a key maps to at most one value.
- Ordering: Some implementations maintain order (insertion or sorted), while others do not.
Essential Operations
associate(K key, V value): Associates the specified value with the specified key.retrieveValue(K key): Returns the value to which the specified key is mapped.dissociate(K key): Removes the mapping for a key if present.keyCollection(): Returns aSetview of the keys.valueCollection(): Returns aCollectionview of the values.entryCollection(): Returns aSetview of the key-value mappings.mappingCount(): Returns the number of key-value mappings.isMapEmpty(): Returnstrueif the map contains no mappings.
Primary Implementations
HashMap: Hash table based implementation. Permitsnullkeys and values. Offers constant-time performance for basic operations.TreeMap: Red-Black tree based navigable map. Stores entries in key-sorted order.LinkedHashMap: Hash table and linked list implementation. Maintains insertion-order or access-order.Hashtable: A legacy, synchronized thread-safe map. Does not allownullkeys or values.ConcurrentHashMap: A highly concurrent, thread-safe map supporting full concurrency for retrievals and high expected concurrency for updates.IdentityHashMap: Uses reference-equality (==) instead of object-equality (equals()) when comparing keys.
Example Usage
Map<String, Integer> inventory = new HashMap<>();
inventory.put("Widgets", 100);
inventory.put("Gadgets", 50);
Integer stock = inventory.get("Widgets"); // Retrieves 100
System.out.println("Widget stock: " + stock);
inventory.remove("Gadgets");
System.out.println("Total item types: " + inventory.size());