Generics and Collections practice questions

From OCP Java SE 8 (1Z0-809) · 25 questions on this topic

Generics and Collections practice questions from OCP Java SE 8 (1Z0-809). This pack has 25 questions tagged Generics and Collections, drawn from its timed mock exams. 8 of them are worked through in full below — the question, every option, why each is right or wrong, and the explanation.

Worked examples for Generics and Collections

  1. Question 1

    What is the result of compiling the following program? ```java import java.util.ArrayList; import java.util.List; public class Main { public static void main(String[] args) { List<? extends Number> nums = new ArrayList<Integer>(); nums.add(1); System.out.println(nums.size()); } } ```

    1. A. An exception is thrown at runtime

      Assumes the failure happens at runtime, but the compiler rejects the add before the program can run, so the method is never reached.

    2. B. Compilation failsCorrect answer

      Correct. An upper-bounded wildcard (? extends Number) makes the list read-only for elements: the compiler only knows it holds some subtype of Number, so it cannot prove adding an Integer is type-safe and rejects the call (JLS 8 §4.5.1).

    3. C. It compiles because 1 is a Number

      The value being a Number is not enough: the compiler cannot know the list's actual element type is Integer — it might be a List<Double> — so it forbids the add rather than trusting the value.

    4. D. 1

      This would be the printed size only if the code compiled and ran; the add is rejected at compile time, so nothing is printed.

    Explanation

    An upper-bounded wildcard makes the list read-only for elements: the compiler only knows it holds some unknown subtype of Number, so it cannot prove that adding an Integer is safe. You can read Numbers out of such a list, but the only value you may add is null, so the add call is rejected at compile time.

  2. Question 2

    What is the output of the following program? ```java import java.util.Arrays; import java.util.Set; import java.util.TreeSet; public class Main { public static void main(String[] args) { Set<Integer> s = new TreeSet<>(Arrays.asList(5, 1, 5, 3)); System.out.println(s); } } ```

    1. A. [1, 3, 5]Correct answer

      Correct. TreeSet drops the duplicate 5 (Set semantics) and stores its elements in natural ascending order, giving 1, 3, 5.

    2. B. [1, 3, 5, 5]

      Keeps the duplicate 5, but no Set stores duplicates — the second 5 is discarded.

    3. C. [5, 1, 3]

      Shows insertion order with duplicates removed, which is LinkedHashSet behavior; a TreeSet re-sorts into natural order instead.

    4. D. [5, 1, 5, 3]

      This is the original list unchanged — it neither removes the duplicate nor sorts, so it matches no Set.

    Explanation

    TreeSet enforces two things at once: Set semantics drop the duplicate 5, and its sorted structure keeps elements in natural ascending order. The result is the distinct values arranged from smallest to largest.

  3. Question 3

    What is the result of compiling the following program? ```java import java.util.Comparator; public class Main { public static void main(String[] args) { Comparator<String> c = Comparator.comparing(s -> s.length()).reversed(); System.out.println(c.compare("aa", "b")); } } ```

    1. A. A positive number

      Assumes the code compiles and compares lengths; the implicit lambda leaves s untyped, so the assignment never compiles and compare is never called.

    2. B. A negative number

      Presumes a running comparison producing a negative result, but inference yields Comparator<Object>, which will not assign to Comparator<String>, so nothing runs.

    3. C. 0

      Would require the comparator to execute and find equal lengths, but the program fails to compile before any comparison can happen.

    4. D. Compilation failsCorrect answer

      Correct. With an implicit lambda, comparing(s -> s.length()) has nothing to pin the type of s, so it infers Comparator<Object>, and chaining .reversed() locks that in before the Comparator<String> target is consulted — the mismatched assignment does not compile (JLS 8 §18).

    Explanation

    With an implicit lambda, comparing(s -> s.length()) has nothing to pin the type of s, so the compiler infers Comparator<Object> — and chaining .reversed() locks that in before the assignment target is consulted. Comparator<Object> doesn't assign to Comparator<String>. Fix: a method reference, an explicit (String s), or Comparator.<String, Integer>comparing.

  4. Question 4

    What is the output of the following program? ```java import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; public class Main { public static void main(String[] args) { List<Integer> l = new ArrayList<>(Arrays.asList(1, 2, 3)); Collections.reverse(l); System.out.println(l); } } ```

    1. A. Compilation fails

      The call is well typed and compiles.

    2. B. [1, 2, 3]

      reverse actually changes the order rather than leaving it untouched.

    3. C. An UnsupportedOperationException is thrown at runtime

      The unsupported-operation risk applies to add or remove on a fixed-size view, not to reversing a real ArrayList.

    4. D. [3, 2, 1]Correct answer

      Correct: reversing the copied list yields the elements in the opposite order.

    Explanation

    Collections.reverse mutates a list in place, and because the elements were copied into a real ArrayList the list fully supports mutation. The result is the elements in reversed order.

  5. Question 5

    What is the output of the following program? (Assume any compiler warnings are ignored.) ```java import java.util.ArrayList; import java.util.List; public class Main { public static void main(String[] args) { List raw = new ArrayList<String>(); raw.add(42); try { String s = (String) raw.get(0); System.out.println(s); } catch (ClassCastException e) { System.out.println("cce"); } } } ```

    1. A. An unhandled exception terminates the program

      The ClassCastException is caught by the surrounding handler, so it does not terminate the program.

    2. B. 42

      The stored value is an Integer, and the cast to String fails before any number could print.

    3. C. Compilation fails because an int cannot be added to a list of String

      Through the raw type the int addition compiles with only a warning, not an error.

    4. D. cceCorrect answer

      Correct: the cast of the stored Integer to String throws ClassCastException, which the catch reports.

    Explanation

    Adding through a raw reference bypasses generic checking, with only an unchecked warning, so an Integer physically lands in the list. The mismatch surfaces only later, when casting that element to String throws a ClassCastException that the code catches.

  6. Question 6

    What is the result of compiling the following program? ```java public class Main { static <N extends Number> double half(N n) { return n.doubleValue() / 2; } public static void main(String[] args) { System.out.println(half("12")); } } ```

    1. A. 6.0

      No value is produced because the call never compiles.

    2. B. Compilation failsCorrect answer

      Correct: the bound excludes String, so inference fails and the program does not compile.

    3. C. A ClassCastException is thrown at runtime

      The error is detected at compile time, not as a runtime cast failure.

    4. D. 12 is parsed and 6.0 is printed

      Generics never parse a string into a number; the bound simply rejects String.

    Explanation

    The type bound restricts the argument to subtypes of Number, and String is not one. Type inference finds no valid type argument for a String argument, so compilation fails at the call.

  7. Question 7

    What is the output of the following program? ```java import java.util.LinkedHashSet; import java.util.Set; public class Main { public static void main(String[] args) { Set<String> s = new LinkedHashSet<>(); s.add("z"); s.add("a"); s.add("m"); s.add("z"); System.out.println(s); } } ```

    1. A. [z, a, m]Correct answer

      Correct. LinkedHashSet preserves insertion order and rejects duplicates, so the second z is ignored and the original z keeps its first position: z, a, m.

    2. B. [z, a, m, z]

      Keeps the duplicate z, but a Set rejects duplicates — the repeated z is not added again.

    3. C. [a, m, z]

      Shows sorted order, which is what a TreeSet would produce; LinkedHashSet keeps insertion order instead.

    4. D. [a, m]

      Drops z entirely; z is a valid distinct element and is kept at its first-inserted position.

    Explanation

    LinkedHashSet preserves insertion order while still rejecting duplicates, unlike a TreeSet, which would re-sort the elements. The duplicate second z is ignored and the first z keeps its original position, giving z, a, m.

  8. Question 8

    What is the output of the following program? ```java import java.util.PriorityQueue; public class Main { public static void main(String[] args) { PriorityQueue<Integer> pq = new PriorityQueue<>(); pq.add(5); pq.add(1); pq.add(3); System.out.println(pq.poll() + " " + pq.poll() + " " + pq.peek()); } } ```

    1. A. 5 1 3

      This is insertion order; a priority queue reorders by priority, not by arrival.

    2. B. 1 3 5Correct answer

      Correct: the two smallest are polled in ascending order and peek then shows the remaining head.

    3. C. 1 3 null

      A null head would require the queue to be empty, but one element is still present at the peek.

    4. D. 5 3 1

      This polls in descending order, which is not how a min-ordered priority queue behaves.

    Explanation

    A priority queue polls its smallest element under natural ordering rather than in insertion order, and peek reports the current head without removing it. After two polls one element remains for peek to return.

Practise all 25 Generics and Collections questions

OCP Java SE 8 has the full set, inside timed mock exams that mirror real exam conditions — every question with a worked explanation.

Open OCP Java SE 8

Other topics in this pack