Common Interview Questions
1. What is the difference between ArrayList and LinkedList?
Section titled “1. What is the difference between ArrayList and LinkedList?”Answer: ArrayList and LinkedList are both List implementations but differ in their internal structure and performance characteristics:
-
Internal Structure:
- ArrayList: Backed by a resizable array
- LinkedList: Implemented as a doubly-linked list
-
Performance:
- ArrayList: O(1) for random access, O(n) for insertions/deletions in the middle
- LinkedList: O(n) for random access, O(1) for insertions/deletions once position is found
-
Memory Overhead:
- ArrayList: Lower memory overhead
- LinkedList: Higher due to storing node pointers
-
Use Cases:
- ArrayList: Preferred for random access and storing data
- LinkedList: Preferred for frequent insertions/deletions, especially at ends
2. How does HashMap work internally?
Section titled “2. How does HashMap work internally?”Answer: HashMap works by storing key-value pairs in an array of buckets:
-
When putting an element:
- The key’s hashCode() is calculated and modified (hash = key.hashCode() ^ (hash >>> 16))
- The bucket index is determined by (hash & (capacity-1))
- If the bucket is empty, the entry is placed there
- If there’s a collision, entries form a linked list (or a tree in Java 8+ when bucket size exceeds 8)
-
When getting an element:
- The same hash calculation determines the bucket
- The key’s equals() method is used to find the correct entry in the bucket
-
Resizing:
- Occurs when the load factor threshold is exceeded (default 0.75)
- Creates a new array with double the capacity
- Rehashes all entries to new positions
3. What is the difference between HashMap and Hashtable?
Section titled “3. What is the difference between HashMap and Hashtable?”Answer:
| Feature | HashMap | Hashtable |
|---|---|---|
| Thread safety | Not thread-safe | Thread-safe (all methods synchronized) |
| Null keys/values | Allows one null key and multiple null values | Does not allow null keys or values |
| Performance | Generally better due to lack of synchronization | Slower due to synchronization overhead |
| Iterator | Fail-fast | Fail-fast |
| Legacy status | Modern implementation | Legacy class (since JDK 1.0) |
| Preferred alternative | Use ConcurrentHashMap for thread safety | Use HashMap or ConcurrentHashMap |
4. What is the difference between fail-fast and fail-safe iterators?
Section titled “4. What is the difference between fail-fast and fail-safe iterators?”Answer:
-
Fail-fast Iterators:
- Throw ConcurrentModificationException if the collection is modified while iterating
- Work on the original collection
- Examples: Iterator from ArrayList, HashMap, HashSet
- Use a modification counter (modCount) to detect changes
-
Fail-safe Iterators:
- Don’t throw exceptions if the collection is modified during iteration
- Work on a copy of the collection
- Examples: Iterator from ConcurrentHashMap, CopyOnWriteArrayList
- May not reflect the latest state of the collection
5. What is the difference between Collection and Collections?
Section titled “5. What is the difference between Collection and Collections?”Answer:
-
Collection: An interface that represents a group of objects. It’s the root interface in the collection hierarchy.
-
Collections: A utility class that contains static methods for operating on collections, such as sorting, searching, synchronization, and creating unmodifiable views.
6. How do you sort a collection of custom objects?
Section titled “6. How do you sort a collection of custom objects?”Answer: There are two ways to sort custom objects:
-
Implement Comparable interface:
public class Employee implements Comparable<Employee> {private String name;private int age;// Constructor, getters, setters...@Overridepublic int compareTo(Employee other) {return this.age - other.age; // Sort by age}}// UsageList<Employee> employees = new ArrayList<>();// Add employees...Collections.sort(employees); // Uses compareTo method -
Use a Comparator:
// External comparatorComparator<Employee> nameComparator = new Comparator<Employee>() {@Overridepublic int compare(Employee e1, Employee e2) {return e1.getName().compareTo(e2.getName());}};// UsageCollections.sort(employees, nameComparator);// Java 8+ lambdaCollections.sort(employees, Comparator.comparing(Employee::getName));
7. What is the difference between List, Set, and Map?
Section titled “7. What is the difference between List, Set, and Map?”Answer:
-
List: An ordered collection that allows duplicate elements. Elements can be accessed by their index.
- Examples: ArrayList, LinkedList
-
Set: A collection that cannot contain duplicate elements. Generally unordered.
- Examples: HashSet, TreeSet, LinkedHashSet
-
Map: An object that maps keys to values. Cannot contain duplicate keys.
- Examples: HashMap, TreeMap, LinkedHashMap
8. What happens when a duplicate key is put into a HashMap?
Section titled “8. What happens when a duplicate key is put into a HashMap?”Answer: When a duplicate key is put into a HashMap, the new value replaces the old value associated with that key. The put() method returns the previous value associated with the key, or null if there was no mapping for the key.
Map<String, Integer> map = new HashMap<>();map.put("key", 1); // Returns null (no previous mapping)Integer previous = map.put("key", 2); // Returns 1 (previous value)System.out.println(map.get("key")); // Prints 29. What is the difference between TreeSet and HashSet?
Section titled “9. What is the difference between TreeSet and HashSet?”Answer:
| Feature | TreeSet | HashSet |
|---|---|---|
| Ordering | Sorted (natural or by comparator) | Unordered |
| Implementation | Red-Black Tree | HashMap |
| Performance | O(log n) for add/remove/contains | O(1) for add/remove/contains |
| Null elements | Not allowed (Java 7+) | One null allowed |
| Memory usage | Less than HashSet | More than TreeSet |
| Use case | When order matters or range operations needed | When fast lookup is priority |
10. How do you create an immutable collection?
Section titled “10. How do you create an immutable collection?”Answer:
In Java 9+, you can use factory methods:
// Immutable ListList<String> immutableList = List.of("a", "b", "c");
// Immutable SetSet<String> immutableSet = Set.of("a", "b", "c");
// Immutable MapMap<String, Integer> immutableMap = Map.of("a", 1, "b", 2, "c", 3);
// For larger mapsMap<String, Integer> largeMap = Map.ofEntries( Map.entry("a", 1), Map.entry("b", 2), // More entries...);In Java 8 and earlier:
// Using Collections utility methodsList<String> list = new ArrayList<>();list.add("a");list.add("b");List<String> immutableList = Collections.unmodifiableList(list);
// Similar methods for Set and MapSet<String> immutableSet = Collections.unmodifiableSet(new HashSet<>());Map<String, Integer> immutableMap = Collections.unmodifiableMap(new HashMap<>());11. What is the difference between Iterator and ListIterator?
Section titled “11. What is the difference between Iterator and ListIterator?”Answer:
| Feature | Iterator | ListIterator |
|---|---|---|
| Direction | Forward only | Bidirectional (forward and backward) |
| Applicable to | All Collection types | Only List implementations |
| Add elements | Cannot add | Can add elements during iteration |
| Replace elements | Cannot replace | Can replace elements with set() |
| Index access | No index methods | Has nextIndex() and previousIndex() |
// Iterator exampleIterator<String> iterator = list.iterator();while (iterator.hasNext()) { String element = iterator.next(); // Can remove but not add or replace if (someCondition) iterator.remove();}
// ListIterator exampleListIterator<String> listIterator = list.listIterator();while (listIterator.hasNext()) { int index = listIterator.nextIndex(); String element = listIterator.next(); // Can remove, add, or replace listIterator.set("new value"); // Replace current element listIterator.add("new element"); // Add after current position}12. What is the ConcurrentModificationException and how do you avoid it?
Section titled “12. What is the ConcurrentModificationException and how do you avoid it?”Answer: ConcurrentModificationException is thrown when a collection is modified while iterating over it using an iterator. This is the behavior of fail-fast iterators.
Ways to avoid it:
-
Use Iterator’s remove() method:
Iterator<String> iterator = list.iterator();while (iterator.hasNext()) {String element = iterator.next();if (someCondition) {iterator.remove(); // Safe way to remove during iteration}} -
Use removeIf() (Java 8+):
list.removeIf(element -> someCondition(element)); -
Use concurrent collections:
List<String> list = new CopyOnWriteArrayList<>();// No ConcurrentModificationException when modifying during iteration -
Create a copy for iteration:
for (String element : new ArrayList<>(originalList)) {if (someCondition) {originalList.remove(element); // Safe because iterating over copy}}
13. How do you synchronize collections in Java?
Section titled “13. How do you synchronize collections in Java?”Answer: There are several ways to synchronize collections in Java:
-
Using Collections utility methods:
List<String> syncList = Collections.synchronizedList(new ArrayList<>());Set<String> syncSet = Collections.synchronizedSet(new HashSet<>());Map<String, Integer> syncMap = Collections.synchronizedMap(new HashMap<>());// Important: Iteration must be manually synchronizedsynchronized (syncList) {for (String item : syncList) {// Safe iteration}} -
Using concurrent collections:
Map<String, Integer> concurrentMap = new ConcurrentHashMap<>();List<String> copyOnWriteList = new CopyOnWriteArrayList<>();Set<String> copyOnWriteSet = new CopyOnWriteArraySet<>();// No explicit synchronization needed for iterationfor (String item : copyOnWriteList) {// Safe iteration} -
Using legacy thread-safe collections:
Vector<String> vector = new Vector<>(); // Thread-safe listHashtable<String, Integer> hashtable = new Hashtable<>(); // Thread-safe map
14. What is the difference between Enumeration and Iterator?
Section titled “14. What is the difference between Enumeration and Iterator?”Answer:
| Feature | Enumeration | Iterator |
|---|---|---|
| Package | java.util | java.util |
| Origin | Legacy (JDK 1.0) | Modern (JDK 1.2) |
| Method names | hasMoreElements(), nextElement() | hasNext(), next() |
| Remove operation | Cannot remove elements | Can remove with remove() |
| Fail-fast | Not fail-fast | Fail-fast |
| Usage | Legacy collections (Vector, Hashtable) | All modern collections |
15. What are the benefits of the Java Collections Framework?
Section titled “15. What are the benefits of the Java Collections Framework?”Answer: The Java Collections Framework provides several benefits:
- Reduced programming effort: Provides ready-to-use data structures and algorithms
- Increased performance: Implementations are highly optimized
- Interoperability: Common interfaces allow collections to work together
- Reduced effort to learn and use: Consistent API across all collection types
- Reusability: Generic implementations that work with any data type
- Extensibility: Framework can be extended with custom implementations