Sequenced Collections practice questions

From OCP Java SE 25 (1Z0-831) · 15 questions on this topic

Sequenced Collections practice questions from OCP Java SE 25 (1Z0-831). This pack has 15 questions tagged Sequenced 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 Sequenced Collections

  1. Question 1

    What does this print? ```java import java.util.*; public class Main { public static void main(String[] args) { LinkedHashMap<String, Integer> m = new LinkedHashMap<>(); m.put("a", 1); m.put("b", 2); m.put("c", 3); m.putLast("a", 1); System.out.print(String.join(",", m.sequencedKeySet())); } } ```

    1. A. a,b,c

      Assumes putLast on an existing key is a no-op; it actually repositions the key to the end.

    2. B. a,b,c,a

      Assumes a duplicate key is appended; map keys are unique, so the key is moved, not duplicated.

    3. C. b,a,c

      Places the key in the middle; putLast moves it all the way to the last position.

    4. D. b,c,aCorrect answer

      putLast on a key already present remaps its value and moves it to the end, so a shifts behind b and c, giving b, c, a in encounter order.

    Explanation

    In a LinkedHashMap the encounter order follows insertion, but putFirst and putLast on a key that already exists are reposition operations, not inserts: they remap the value and move the key to that end. Because map keys are unique, no duplicate entry is created, so re-adding an existing key at the end shifts it behind the others. This mirrors addFirst/addLast on a SequencedSet, which likewise move an existing element rather than adding a second one.

  2. Question 2

    An empty ArrayList is held in a SequencedCollection variable. What is the result of running this code? ```java import java.util.*; public class Main { public static void main(String[] args) { SequencedCollection<String> c = new ArrayList<>(); System.out.print(c.getLast()); } } ```

    1. A. Prints null

      Returning null is Deque.peekLast behaviour; the get-family accessors throw rather than returning null on empty.

    2. B. Prints an empty line

      Assumes a benign empty result; the call throws before any print happens.

    3. C. Throws NoSuchElementExceptionCorrect answer

      getFirst and getLast are specified to throw NoSuchElementException on an empty collection, consistent with Deque.getLast and Iterator.next, so the call throws before printing.

    4. D. Throws IndexOutOfBoundsException

      IndexOutOfBoundsException is what get(int) throws for a bad index; the no-arg end accessors throw NoSuchElementException instead.

    Explanation

    The sequenced end-accessors getFirst and getLast have no element to return on an empty collection, and the spec makes them throw NoSuchElementException rather than return null. This distinguishes them from Deque's peekFirst/peekLast, which return null on empty, and from get(int), which throws IndexOutOfBoundsException for an out-of-range index. Because the throw happens on the accessor call, nothing is printed. The exam often swaps these throw-versus-null behaviours to bait you.

  3. Question 3

    Here rev is the reverse-ordered view returned by m.reversed(), and the new entry is added through that view. Note that both printed values are read back from m, not from rev. What is printed? ```java import java.util.*; public class Main { public static void main(String[] args) { LinkedHashMap<String, Integer> m = new LinkedHashMap<>(); m.put("a", 1); m.put("b", 2); m.put("c", 3); SequencedMap<String, Integer> rev = m.reversed(); rev.putFirst("d", 4); System.out.println(m.lastEntry() + " " + m.firstEntry()); } } ```

    1. A. c=3 a=1

      Assumes the reversed view is a detached snapshot so the backing map never changes; the view is live and write-through.

    2. B. c=3 d=4

      Reads putFirst on the view as putFirst on the backing map; first in the reversed view is last in the map, so the new entry is appended at the end.

    3. C. d=4 a=1Correct answer

      The reversed view is live and write-through, so putFirst on it appends to the end of the backing map, leaving the new entry last while the original first entry is unchanged.

    4. D. Throws UnsupportedOperationException

      Assumes the reversed view is unmodifiable; a LinkedHashMap's reversed view is mutable, so putFirst succeeds.

    Explanation

    A SequencedMap's reversed() returns a live, write-through view whose encounter order is the inverse of the backing map's, so the view's first position corresponds to the map's last position. A structural change through the view is reflected in the backing map at the mirrored end. A LinkedHashMap's reversed view is mutable, so the insertion is permitted.

  4. Question 4

    Does this compile, and if so what does it print? ```java import java.util.*; public class Main { public static void main(String[] args) { HashSet<Integer> s = new HashSet<>(List.of(1, 2, 3)); System.out.println(s.getFirst()); } } ```

    1. A. Prints 1

      Assumes HashSet iterates in insertion order and has getFirst; a plain hash set has no defined encounter order and no such method.

    2. B. Compilation fails: HashSet has no getFirst() methodCorrect answer

      getFirst is declared on SequencedCollection, which HashSet does not implement, so javac reports cannot find symbol at compile time.

    3. C. Prints 3

      Makes the same ordering assumption; HashSet has no specified order and no getFirst to call.

    4. D. Throws NoSuchElementException at runtime

      The code never runs -- the error is detected at compile time, not thrown at runtime.

    Explanation

    HashSet has no defined encounter order, so it was not retrofitted with the sequenced end-accessors; getFirst and getLast are declared on SequencedCollection and SequencedSet. Only the sequenced implementations -- LinkedHashSet and the SortedSet family -- carry these methods, so calling getFirst on a HashSet is a compile-time cannot-find-symbol error. Switching to LinkedHashSet would make it compile and yield a first element.

  5. Question 5

    What does this print? ```java import java.util.*; public class Main { public static void main(String[] args) { LinkedHashMap<String, Integer> m = new LinkedHashMap<>(); m.put("a", 1); m.put("b", 2); m.put("c", 3); SequencedMap<String, Integer> rev = m.reversed(); System.out.print(rev.firstEntry() + " " + rev.sequencedValues()); } } ```

    1. A. c=3 [3, 2, 1]Correct answer

      The reversed view's encounter order is c, b, a, so firstEntry is c=3 and sequencedValues follows the same order, giving [3, 2, 1].

    2. B. a=1 [1, 2, 3]

      Reads the original map and ignores that reversed() flips the order the view exposes.

    3. C. c=3 [1, 2, 3]

      Gets firstEntry right but leaves the values in forward order; sequencedValues follows the view's reversed order too.

    4. D. a=1 [3, 2, 1]

      Reverses the values but reads firstEntry from the original forward order; reversed() flips both accessors consistently.

    Explanation

    reversed() on a SequencedMap returns a view whose encounter order is the inverse of the original, and every order-derived accessor reports that reversed order consistently. So firstEntry, lastEntry, sequencedKeySet, sequencedValues and sequencedEntrySet all follow the flipped order together. Reversing one accessor while leaving another in forward order is the mistake to avoid.

  6. Question 6

    Which two statements about SequencedMap and the sequenced-collection hierarchy in Java 25 are correct? (Choose two.)

    1. A. The Map.Entry returned by LinkedHashMap.firstEntry() is an unmodifiable copy, so calling setValue on it throws UnsupportedOperationException instead of updating the map.Correct answer

      Correct: SequencedMap's entry accessors return a snapshot entry detached from the map (on JDK 25 a NullableKeyValueHolder) that is deliberately immutable, so setValue on it throws UnsupportedOperationException instead of quietly re-writing the map.

    2. B. HashMap implements SequencedMap in Java 25, so firstEntry() on a HashMap compiles and returns whichever entry currently sits in the lowest-numbered bucket.

      Fails at compile time with `cannot find symbol: method firstEntry()`; a HashMap has no defined encounter order and does not implement SequencedMap — only LinkedHashMap and SortedMap/TreeMap do.

    3. C. pollFirstEntry() on a LinkedHashMap removes and returns the head entry, but on an empty map it returns null rather than throwing an exception.Correct answer

      Correct: the poll methods detach and return the head/tail entry, and their empty-map contract is null-returning (like Deque.pollFirst), unlike getFirst()/getLast() which throw NoSuchElementException on an empty collection.

    4. D. Because Deque already declared addFirst, addLast, getFirst and getLast, Deque was deliberately left outside the sequenced hierarchy, so an ArrayDeque cannot be assigned to a SequencedCollection variable.

      Inverts the actual design; Deque's pre-existing addFirst/addLast/getFirst/getLast are exactly why JEP 431 made Deque extend SequencedCollection, so an ArrayDeque IS a SequencedCollection and can be assigned to one.

    Explanation

    Why `The Map.Entry returned by LinkedHashMap.firstEntry() ...` is correct: SequencedMap's four entry accessors (`firstEntry`, `lastEntry`, `pollFirstEntry`, `pollLastEntry`) are specified to hand back a snapshot entry that is detached from the map — on JDK 25 the concrete type is `jdk.internal.util.NullableKeyValueHolder`. It is deliberately immutable, so `m.firstEntry().setValue(99)` throws UnsupportedOperationException instead of quietly re-writing the map through a back door. Why `pollFirstEntry() on a LinkedHashMap removes and returns ...` is correct: the poll methods are the destructive pair — they detach and return the head/tail entry. Their empty-map contract is null-returning, matching `Deque.pollFirst()` rather than the throwing style of `getFirst()`. This asymmetry is examinable: `getFirst()` on an empty SequencedCollection throws NoSuchElementException, while `pollFirstEntry()` on an empty SequencedMap simply yields null. Why the others are wrong: `Because Deque already declared addFirst, addLast, getFirst ...` inverts the actual design. Deque's pre-existing methods are exactly WHY it was retrofitted so cleanly: JEP 431 made `Deque extends SequencedCollection`, so `SequencedCollection<Integer> sc = new ArrayDeque<>(List.of(1, 2, 3));` compiles and `sc.getFirst()` returns 1. `HashMap implements SequencedMap in Java 25, so firstEntry() on a HashMap ...` fails at compile time — `cannot find symbol: method firstEntry()`. A HashMap has no defined encounter order, so there is no meaningful first entry to return; SequencedMap is implemented by LinkedHashMap and by SortedMap/TreeMap, never by HashMap. Exam tip: sort the sequenced API by its empty-collection behaviour. `getFirst`/`getLast`/`removeFirst`/`removeLast` throw NoSuchElementException; the map's `firstEntry`/`lastEntry`/`pollFirstEntry`/`pollLastEntry` return null. And remember the hierarchy line-up — List, Deque, LinkedHashSet and SortedSet are sequenced; HashSet and HashMap are not, and reaching for a sequenced method on them is a compile error, not a runtime one.

  7. Question 7

    The reversed view is obtained BEFORE the two mutations, and both mutations are applied to base, not to view. What does this print? ```java import java.util.*; public class Main { public static void main(String[] args) { List<String> base = new ArrayList<>(List.of("a", "b", "c")); List<String> view = base.reversed(); base.addLast("d"); base.removeFirst(); System.out.print(view); } } ```

    1. A. [d, c, b]Correct answer

      Correct: reversed() is a live view, not a copy, so after addLast and removeFirst the backing list is [b, c, d], and reading the view walks it backwards to [d, c, b].

    2. B. Throws ConcurrentModificationException

      Confuses a view with an iterator; a reversed view is re-read from the backing list on every operation and is not iterating, so mutating the source between creation and use is legal, not a ConcurrentModificationException.

    3. C. [d, c, b, a]

      A half-live belief that additions to the backing list show through but removals do not; a view holds no state of its own, so both writes are equally visible and a is genuinely gone.

    4. D. [c, b, a]

      The snapshot misconception: assumes reversed() eagerly builds a reversed copy at the call, freezing the original three elements; the view references the list, not its contents.

    Explanation

    Trace: `reversed()` does not copy anything — it returns a live, reverse-ordered *view* backed by the same list. Nothing is snapshotted at the moment `view` is created. The two mutations run against `base`: `addLast("d")` makes it `[a, b, c, d]`, then `removeFirst()` makes it `[b, c, d]`. Printing `view` walks that current content backwards, giving `[d, c, b]`. Why the others are wrong: `[c, b, a]` is the snapshot misconception — it is what you get if you believe `reversed()` eagerly builds a reversed copy at the point of the call, freezing the original three elements. The view holds a reference to the list, not to its contents. `[d, c, b, a]` encodes a half-live belief: additions to the backing list show through but removals do not. A view has no state of its own to be stale, so both writes are equally visible; `a` is genuinely gone from the backing list. `Throws ConcurrentModificationException` confuses a view with an iterator. Iterators are fail-fast and do detect structural modification of their source, but a reversed view is not iterating — it is re-read from the backing list on every operation, so mutating the source between creation and use is entirely legal. Exam tip: every `reversed()` in JEP 431 (List, SequencedSet, SequencedMap, Deque) is a view, never a copy — writes flow both ways and reads are always current. The reverse trap is just as common: mutating through `reversed()` changes the ORIGINAL collection, so `list.reversed().addFirst(x)` appends `x` to the tail of `list`.

  8. Question 8

    Which two statements about the sequenced-collection API in Java 25 are correct? (Choose two.)

    1. A. On a TreeSet held as a SequencedSet, getFirst() returns the smallest element and getLast() the largest.Correct answer

      A TreeSet is a SortedSet and hence a SequencedSet whose encounter order is comparator order, so getFirst yields the minimum and getLast the maximum.

    2. B. HashSet gained getFirst()/getLast() when the collection hierarchy was retrofitted with SequencedSet.

      HashSet was not retrofitted: it has no defined encounter order, so it has no getFirst/getLast. Only LinkedHashSet and the SortedSet family are SequencedSet.

    3. C. reversed() returns an independent copy, so later changes to the original are not visible through it.

      reversed() is a live write-through view, not a copy, so changes to the backing collection are visible through it and supported writes flow back.

    4. D. A Deque is a SequencedCollection, so addFirst/addLast and getFirst/getLast are all available on it.Correct answer

      JEP 431 retrofits Deque to extend SequencedCollection, and Deque already declared addFirst/addLast/getFirst/getLast, so every Deque exposes the full set.

    Explanation

    The retrofit maps List and Deque onto SequencedCollection, LinkedHashSet and SortedSet onto SequencedSet, and LinkedHashMap and SortedMap onto SequencedMap, while HashSet and HashMap stay unsequenced. On sorted types the encounter order is comparator order, so the end-accessors return the minimum and the maximum. And reversed() is always a live view over the backing collection, never an independent copy, so writes and later changes flow through it.

Practise all 15 Sequenced Collections questions

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

Open OCP Java SE 25

Other topics in this pack