1. What is the difference between Collection and Collections in Java?
Collection is an interface in Java that defines the root of the collection hierarchy (List, Set, Queue).
It represents a group of objects. Collections is a utility class in java.util that provides static methods
like sort(), binarySearch(), synchronizedList(). So, Collection is about defining behavior, while
Collections is about providing helper methods.
2. Explain the difference between List, Set, and Map.
List allows duplicate elements and maintains insertion order (e.g., ArrayList, LinkedList). Set does
not allow duplicates and order depends on implementation (HashSet: unordered, LinkedHashSet:
insertion-order, TreeSet: sorted). Map stores key-value pairs, keys are unique, values can be
duplicate (HashMap, TreeMap). In short: List → duplicates allowed, Set → unique elements, Map
→ key-value store.
3. How does HashMap work internally?
HashMap uses an array of buckets where each bucket is a linked list or tree. Key’s hashCode()
determines the bucket index, and then equals() checks for equality. In case of collision, elements
are added to the same bucket. From Java 8, if collisions exceed a threshold (8), the linked list is
converted into a balanced Red-Black Tree for faster lookups. Average time complexity is O(1), but
worst case is O(log n) after treeification.
4. What are the differences between ArrayList and LinkedList?
ArrayList is backed by a dynamic array, provides O(1) random access but insert/delete in middle is
O(n). LinkedList is backed by a doubly linked list, good for insert/delete operations O(1) at head/tail
but random access is O(n). In practice, ArrayList is better for read-heavy operations, LinkedList is
better for frequent insert/delete.
5. What is the difference between HashSet and TreeSet?
HashSet is backed by HashMap, does not maintain order, operations like add/remove/contains are
O(1). TreeSet is backed by TreeMap, maintains sorted order of elements, and operations are O(log
n). HashSet is faster but unordered; TreeSet is slower but keeps elements sorted.
6. Why does HashSet not allow duplicate elements?
HashSet uses HashMap internally where keys must be unique. When you insert an element, it
checks hashCode() and equals(). If both match with an existing element, the new element is not
added. This mechanism ensures uniqueness in HashSet.
7. What is the difference between fail-fast and fail-safe iterators?
Fail-fast iterators (like in ArrayList, HashMap) throw ConcurrentModificationException if collection is
structurally modified during iteration. Fail-safe iterators (like in CopyOnWriteArrayList,
ConcurrentHashMap) work on a clone of the collection, so they don’t throw exception but might not
reflect latest changes. Fail-fast is faster but unsafe in concurrent use, fail-safe is safer but costlier.
8. When would you use Iterator vs ListIterator?
Iterator can be used to traverse any collection (List, Set, Queue) but it only allows forward traversal
and element removal. ListIterator is specific to Lists and allows bidirectional traversal, element
addition, and modification during iteration. Use Iterator for generic traversal, use ListIterator for
List-specific, advanced operations.
9. How does a HashMap handle collisions internally?
A collision happens when two keys have the same hash bucket index. HashMap stores collided
entries in a linked list (pre-Java 8) or Red-Black Tree (Java 8+) if collisions exceed threshold.
During retrieval, HashMap compares hashCode first, then equals() to identify the correct key-value
pair.
10. What is the initial capacity and load factor in HashMap?
Initial capacity = number of buckets created initially (default 16). Load factor = threshold to resize
HashMap (default 0.75). For example, if capacity = 16 and load factor = 0.75, HashMap resizes
when 12 entries are filled. This mechanism balances memory usage vs performance.
11. When does HashMap convert its bucket from LinkedList to Red-Black Tree?
In Java 8, if too many collisions occur in a bucket, and the number of entries in that bucket exceeds
TREEIFY_THRESHOLD (8), the linked list is converted to a Red-Black Tree. This reduces
worst-case lookup time from O(n) to O(log n). It only happens if the overall HashMap capacity is at
least 64; otherwise, resizing occurs instead of treeification.
12. Difference between ConcurrentHashMap and Hashtable.
Both are thread-safe, but their locking mechanisms differ. Hashtable locks the entire map for every
operation, leading to contention and poor performance. ConcurrentHashMap divides the map into
segments (Java 7) or buckets with finer-grained locks (Java 8 uses CAS + synchronized blocks at
bucket level). Hence, ConcurrentHashMap offers much better concurrency and scalability.
13. How does CopyOnWriteArrayList work internally?
It is a thread-safe variant of ArrayList. Whenever you modify it (add, remove, set), it creates a new
copy of the underlying array and applies the change. Iterators operate on a snapshot of the array,
so they don’t throw ConcurrentModificationException. Advantage: great for read-heavy, concurrent
applications. Drawback: costly for frequent writes due to array copy overhead.
14. What are WeakHashMap and its use cases?
WeakHashMap stores keys as weak references, so if a key is no longer strongly referenced
elsewhere, it becomes eligible for garbage collection. The entry gets automatically removed from
the map. Useful in caching, where you don’t want keys to prevent GC, e.g., storing metadata or
temporary objects. Unlike HashMap, it avoids memory leaks when keys are no longer in use.
15. What is the difference between Comparable and Comparator?
Comparable is an interface used to define the natural ordering of objects. It modifies the class itself
by implementing compareTo(). Comparator is a separate interface that defines custom sorting logic
via compare(). It allows multiple sort sequences without modifying the original class. Example:
String implements Comparable (alphabetical order), but you can use Comparator to sort Strings by
length.
16. Explain the difference between HashMap and LinkedHashMap.
Both store key-value pairs, but HashMap doesn’t maintain any order of keys. LinkedHashMap
maintains insertion order (or access order if configured with accessOrder flag). Performance is
similar, but LinkedHashMap uses a doubly-linked list internally to maintain order. Common use
case: caching, where predictable iteration order is required.
17. How does PriorityQueue work internally?
PriorityQueue is a queue that orders elements based on natural ordering or a provided Comparator.
Internally, it uses a binary heap data structure stored in an array. The head of the queue is always
the smallest (min-heap by default). Insertion and deletion take O(log n), while peek() is O(1). Useful
for scheduling tasks, job queues, or implementing Dijkstra’s algorithm.
18. What is EnumMap and when to use it?
EnumMap is a specialized Map implementation with enum keys. It stores mappings in an internal
array indexed by ordinal values of the enum. This makes it very fast and memory efficient
compared to HashMap. Use EnumMap when keys are fixed enum types, e.g., mapping days of the
week to schedules or statuses to actions.
19. Difference between IdentityHashMap and HashMap.
HashMap compares keys using equals() and hashCode(). IdentityHashMap uses == operator for
key comparison, so two objects with the same content but different references are treated as
different keys. It’s not commonly used but can be helpful in special cases like object graph traversal
or serialization frameworks.
20. What is the difference between deep copy and shallow copy in collections?
A shallow copy copies only references of objects, not the actual objects. Changes in original
elements affect the copied collection. A deep copy creates new independent objects for every
element, so changes in one collection don’t affect the other. Example: clone() in ArrayList gives a
shallow copy, while serialization or manual copying can give a deep copy.
21. Explain the time complexity of major collection operations (List, Set, Map).
For ArrayList, get/set is O(1), add is amortized O(1), remove in middle is O(n). For LinkedList,
add/remove at ends is O(1), but random access is O(n). For HashSet/HashMap, put/get/remove is
O(1) average, O(log n) worst-case due to treeification. For TreeSet/TreeMap, all operations (put,
get, remove) are O(log n). Choosing the right collection impacts performance significantly.
22. How does ConcurrentHashMap achieve thread-safety without locking the entire map?
Pre-Java 8: used segment-level locking, dividing the map into buckets and locking only the
segment. Java 8+: replaced with bucket-level locking using CAS (Compare-And-Swap) and
synchronized blocks for writes, reducing contention. Reads are lock-free, writes are fine-grained.
This makes ConcurrentHashMap highly scalable in multi-threaded environments.
23. Why was ConcurrentModificationException introduced?
It occurs when a collection is structurally modified while iterating with a fail-fast iterator. The
purpose is to fail quickly and alert developers that concurrent modification is unsafe. This prevents
unpredictable behavior like infinite loops, data corruption, or missed elements. Safe alternatives are
fail-safe collections like CopyOnWriteArrayList or ConcurrentHashMap.
24. What are NavigableSet and NavigableMap?
They are extensions of SortedSet and SortedMap, introduced in Java 6. NavigableSet (e.g.,
TreeSet) provides methods like higher(), lower(), ceiling(), floor() for closest element searches.
NavigableMap (e.g., TreeMap) offers methods like firstEntry(), lastEntry(), pollFirstEntry(),
pollLastEntry(). Useful in scenarios like range queries, ordered navigation, and scheduling systems.
25. Explain internal working of TreeMap (Red-Black Tree).
TreeMap stores key-value pairs in a self-balancing Red-Black Tree. Keys are sorted based on
natural order or a provided Comparator. Red-Black Tree ensures balanced height, so operations
(get, put, remove) are O(log n). It is ideal when you need ordered maps or range-based queries.
26. How does Java handle immutability with Collections (e.g., Collections.unmodifiableList)?
Collections.unmodifiableXXX() returns a wrapper around the original collection. Any attempt to
modify (add, remove, set) throws UnsupportedOperationException. However, if the underlying
collection is modified directly, changes are still reflected. For true immutability, use immutable
libraries (Guava, Java 9 List.of()).
27. What is BlockingQueue and where have you used it in real-time systems?
BlockingQueue is a thread-safe queue that supports operations like put() and take(), which block if
the queue is full or empty. Common implementations: ArrayBlockingQueue, LinkedBlockingQueue,
PriorityBlockingQueue. Widely used in producer-consumer problems, task scheduling, thread
pools, and message pipelines.
28. Explain the difference between parallelStream and normal stream on collections.
A normal stream processes elements sequentially using a single thread. A parallelStream divides
the collection into multiple chunks and processes them in parallel using ForkJoinPool.
ParallelStream improves performance for large, CPU-intensive tasks but can degrade performance
for small or I/O-heavy tasks due to overhead. Always benchmark before using.
29. What is Spliterator in Java? How is it different from Iterator?
Spliterator (Java 8) is designed for parallel processing. It supports methods like trySplit() to partition
data for parallel execution. Iterator supports sequential traversal only. Spliterator also provides
characteristics (ORDERED, DISTINCT, SORTED) for better optimization. Mainly used internally by
streams for efficient parallelism.
30. In real projects, when would you prefer ArrayList, LinkedList, or CopyOnWriteArrayList?
ArrayList: best for read-heavy, random-access scenarios (e.g., caching, lookups). LinkedList: best
for frequent insertions/deletions in the middle (though rarely chosen in practice).
CopyOnWriteArrayList: ideal for multi-threaded read-heavy applications with infrequent writes, like
subscriber lists or configuration data. Choice depends on read-write ratio and concurrency needs.