OCP Generics and Collections 2 — Questions and Answers
Question 1: What is the result of compiling and running the following code? ```java List<String> list = new ArrayList<>(); list.add("A"); List<Object> objList = list; objList.add(42); System.out.println(list.get(1)); ```
- Prints 42
- Compile error: incompatible types (Correct answer)
- ClassCastException at runtime
- Prints null
Correct answer: Compile error: incompatible types
A List<String> cannot be assigned to List<Object> because generic types are invariant in Java, causing a compile-time error.
Question 2: Which method signature correctly uses a lower-bounded wildcard to accept a List of Number or any supertype?
- void process(List<? extends Number> list)
- void process(List<? super Number> list) (Correct answer)
- void process(List<Number> list)
- void process(List<?> list)
Correct answer: void process(List<? super Number> list)
The lower-bounded wildcard `? super Number` accepts List<Number>, List<Object>, or any list whose type is a supertype of Number.
Question 3: What does the Collections.unmodifiableList() method return?
- A new immutable copy of the list
- A view that throws UnsupportedOperationException on mutation (Correct answer)
- A synchronized wrapper around the list
- A deep-cloned list with no backing reference
Correct answer: A view that throws UnsupportedOperationException on mutation
Collections.unmodifiableList() returns a view backed by the original list; structural modifications through the view throw UnsupportedOperationException.
Question 4: Which statement about TreeMap is correct?
- It allows one null key by default
- It maintains keys in insertion order
- It maintains keys in natural sorted order (Correct answer)
- It is backed by a hash table
Correct answer: It maintains keys in natural sorted order
TreeMap stores keys in their natural ordering (or by a provided Comparator), unlike HashMap which uses hashing.
Question 5: Given `Map<String, List<Integer>> map`, which generic method call compiles without an unchecked warning?
- map.put("k", Arrays.asList(1, 2, 3)) (Correct answer)
- map.put("k", new ArrayList())
- map.put("k", (List<Integer>) new ArrayList())
- map.put("k", List.of("1", "2"))
Correct answer: map.put("k", Arrays.asList(1, 2, 3))
Arrays.asList(1, 2, 3) infers List<Integer> from the declared map type, so no unchecked warning is generated.
Question 6: What happens when you call Iterator.remove() before calling Iterator.next()?
- It removes the last element of the collection
- It throws IllegalStateException (Correct answer)
- It throws NoSuchElementException
- It silently does nothing
Correct answer: It throws IllegalStateException
Iterator.remove() requires a prior call to next(); calling remove() without it throws IllegalStateException.
Question 7: Which collection class is most appropriate for a LIFO (last-in, first-out) stack in modern Java?
- java.util.Stack
- java.util.ArrayDeque (Correct answer)
- java.util.LinkedList used as Queue
- java.util.PriorityQueue
Correct answer: java.util.ArrayDeque
ArrayDeque is recommended over the legacy Stack class for LIFO operations because it is faster and not synchronized.
What is the result of compiling and running the following code?
```java
List list = new ArrayList<>();
list.add("A");
List objList = list;
objList.add(42);
System.out.println(list.get(1));
```