Java Interview Questions
Java Collections Framework - Theory Questions
1. What is the Java Collections Framework and what are its main advantages?
The Java Collections Framework is a unified architecture for representing and manipulating collections. Main advantages:
- Reduces programming effort: Ready-to-use data structures
- Increases performance: High-performance implementations
- Promotes reuse: Interoperable API
- Reduces effort to learn: Standardized interface hierarchy
- Software quality: Well-tested, robust implementations
2. What are the main interfaces in the Collections Framework?
Core interfaces in Collections Framework:
- Collection: Root interface for all collections (except Map)
- List: Ordered collection, allows duplicates
- Set: Unordered collection, no duplicates
- Queue: Designed for holding elements prior to processing
- Deque: Double-ended queue
- Map: Key-value pairs, not part of Collection interface
- SortedSet & SortedMap: Sorted versions of Set and Map
3. What is the difference between List, Set, and Map?
List:
- Ordered collection (insertion order)
- Allows duplicate elements
- Index-based access
- Examples: ArrayList, LinkedList
Set:
- Unordered collection (except LinkedHashSet)
- No duplicate elements
- No index-based access
- Examples: HashSet, TreeSet
Map:
- Key-value pairs
- Keys are unique, values can duplicate
- Not part of Collection interface
- Examples: HashMap, TreeMap
4. What is the difference between ArrayList and LinkedList?
ArrayList:
- Backed by dynamic array
- Fast random access (O(1))
- Slow insertions/deletions in middle (O(n))
- Better for frequent access, less modifications
- Implements RandomAccess interface
LinkedList:
- Backed by doubly linked list
- Slow random access (O(n))
- Fast insertions/deletions (O(1)) if position known
- Better for frequent modifications
- Implements Queue and Deque interfaces
5. What is the difference between HashSet, LinkedHashSet, and TreeSet?
HashSet:
- Uses HashMap internally
- No ordering guarantees
- Fastest operations (O(1) average)
- Allows one null element
LinkedHashSet:
- Maintains insertion order
- Slightly slower than HashSet
- Uses LinkedList to maintain order
TreeSet:
- Maintains sorted order (natural or comparator)
- Implements NavigableSet
- Slower operations (O(log n))
- Doesn't allow null (if natural ordering used)
6. What is the difference between HashMap, LinkedHashMap, and TreeMap?
HashMap:
- No ordering guarantees
- Fastest operations (O(1) average)
- Allows one null key and multiple null values
- Not synchronized
LinkedHashMap:
- Maintains insertion order or access order
- Slightly slower than HashMap
- Good for LRU cache implementation
TreeMap:
- Maintains sorted order by keys
- Implements NavigableMap
- Slower operations (O(log n))
- Doesn't allow null keys (if natural ordering used)
7. What is the fail-fast iterator and how does it work?
A fail-fast iterator immediately throws ConcurrentModificationException if the collection is structurally modified after iterator creation (except through iterator's own methods).
How it works:
- Maintains a modification count (modCount)
- Checks modCount on each operation
- Throws exception if modCount changed unexpectedly
Collections with fail-fast iterators: ArrayList, HashSet, HashMap
Example of unsafe modification:
List
list.add("A");
Iterator
list.add("B"); // Structural modification
it.next(); // Throws ConcurrentModificationException
8. What is the fail-safe iterator and how does it work?
A fail-safe iterator operates on a copy of the collection, so it doesn't throw ConcurrentModificationException.
Characteristics:
- Works with concurrent collections
- Doesn't reflect latest changes immediately
- No performance overhead for modification detection
Collections with fail-safe iterators: CopyOnWriteArrayList, ConcurrentHashMap
Example:
List
list.add("A");
Iterator
list.add("B"); // Safe modification
it.next(); // No exception, but won't see "B"
9. What is the Comparable interface and how is it used?
The Comparable interface defines natural ordering of objects. It contains one method:
public int compareTo(T o);
Usage:
- Implemented by class whose objects need sorting
- Used by Collections.sort() and TreeSet/TreeMap
- Defines default/natural ordering
Example:
class Student implements Comparable
private String name;
public int compareTo(Student other) {
return this.name.compareTo(other.name);
}
}
10. What is the Comparator interface and how is it different from Comparable?
The Comparator interface defines custom ordering. Key differences:
Comparable:
- Single sorting sequence (natural ordering)
- Modifies the original class
- compareTo() method with one parameter
Comparator:
- Multiple sorting sequences
- Doesn't modify original class
- compare() method with two parameters
Example:
Comparator
s1.getName().compareTo(s2.getName());
11. How does HashMap work internally in Java?
HashMap internal working:
- Uses array of buckets (Node
- Uses hashCode() to determine bucket index
- Handles collisions using linked list or tree (Java 8+)
- When load factor (0.75 by default) is exceeded, rehashing occurs
- In Java 8+, when bucket size > 8, linked list converts to tree
- Provides O(1) average time for get() and put()
Key methods involved: hashCode(), equals(), put(), get()
12. What is the importance of hashCode() and equals() methods in Collections?
hashCode():
- Used by hash-based collections (HashMap, HashSet) to determine bucket
- Should be consistent with equals()
- Equal objects must have equal hashCodes
equals():
- Used to check object equality
- Used by all collections for containment checks
- Must be reflexive, symmetric, transitive, consistent
Contract: If a.equals(b) is true, then a.hashCode() == b.hashCode() must be true.
13. What are the different ways to iterate over Collections?
Various iteration methods:
For-each loop: for (Element e : collection) { ... }
Iterator: Iterator
ListIterator: (for List) - bidirectional traversal
Enumeration: Legacy interface, similar to Iterator
Java 8 forEach: collection.forEach(element -> { ... });
Stream API: collection.stream().forEach(...);
14. What is the difference between Collection and Collections?
Collection:
- Root interface in Collection hierarchy
- Represents a group of objects
- Subinterfaces: List, Set, Queue
- Defines basic operations like add, remove, contains
Collections:
- Utility class in java.util package
- Contains static methods for collection operations
- Provides algorithms like sort, reverse, shuffle
- Provides synchronization wrappers
- Provides immutable empty collections
15. What are the concurrent collection classes in Java?
Thread-safe concurrent collections:
- ConcurrentHashMap: Thread-safe HashMap alternative
- CopyOnWriteArrayList: Thread-safe List for read-heavy operations
- CopyOnWriteArraySet: Thread-safe Set implementation
- ConcurrentSkipListMap: Concurrent navigable map
- ConcurrentSkipListSet: Concurrent navigable set
- BlockingQueue implementations: ArrayBlockingQueue, LinkedBlockingQueue
These provide better performance than synchronized wrappers.
16. What is the difference between synchronized collections and concurrent collections?
Synchronized Collections:
- Created using Collections.synchronizedXXX() methods
- Use intrinsic locking (synchronized blocks)
- Thread-safe but poor performance under high contention
- Lock entire collection during operations
- Fail-fast iterators
Concurrent Collections:
- Part of java.util.concurrent package
- Use advanced concurrency techniques
- Better performance through fine-grained locking
- Allow concurrent reads and limited concurrent writes
- Fail-safe or weakly consistent iterators
17. What are the Queue implementations and their characteristics?
Common Queue implementations:
- PriorityQueue: Unbounded, elements ordered by natural ordering or comparator
- ArrayDeque: Resizable array implementation, faster than Stack
- LinkedList: Can be used as Queue, implements both List and Deque
- ArrayBlockingQueue: Bounded, blocking, thread-safe
- LinkedBlockingQueue: Optionally bounded, blocking, thread-safe
- PriorityBlockingQueue: Unbounded, blocking, thread-safe version of PriorityQueue
18. What are the best practices for using Collections in Java?
Best practices:
- Use interface types for declarations: List
- Prefer isEmpty() over size() == 0 for readability
- Use diamond operator: new ArrayList<>()
- Choose the right collection type for your use case
- Override hashCode() and equals() properly for custom objects
- Use Collections utility methods instead of writing your own
- Consider capacity for ArrayList and HashMap if size is known
- Use concurrent collections for multi-threaded environments
- Prefer for-each loop over manual iteration when possible
19. What is the load factor in HashMap and how does it affect performance?
The load factor is a measure of how full the hash table is allowed to get before its capacity is automatically increased.
- Default load factor: 0.75
- When entries > (capacity * load factor), rehashing occurs
- Higher load factor: Less memory, more collisions
- Lower load factor: More memory, fewer collisions
- Trade-off between time and space complexity
Example: For initial capacity 16 and load factor 0.75, rehashing occurs when 12th element is added.
20. How do you choose the right collection for your use case?
Selection guidelines:
- Need key-value pairs? → Map
- Allow duplicates and need ordering? → List
- No duplicates? → Set
- FIFO/LIFO processing? → Queue/Deque
- Fast access by index? → ArrayList
- Frequent insertions/deletions? → LinkedList
- Need sorting? → TreeSet/TreeMap
- Need fastest access? → HashSet/HashMap
- Need insertion order? → LinkedHashSet/LinkedHashMap
- Thread-safe requirement? → Concurrent collections