Browse Certification Practice Tests by Exam Family

Java 17 1Z0-829: Working with Arrays and Collections

Try 10 focused Java 17 1Z0-829 questions on Working with Arrays and Collections, with explanations, then continue with IT Mastery.

On this page

Open the matching IT Mastery practice page for timed mocks, topic drills, progress tracking, explanations, and full practice.

Try Java 17 1Z0-829 on Web View full Java 17 1Z0-829 practice page

Topic snapshot

FieldDetail
Exam routeJava 17 1Z0-829
Topic areaWorking with Arrays and Collections
Blueprint weight10%
Page purposeFocused sample questions before returning to mixed practice

How to use this topic drill

Use this page to isolate Working with Arrays and Collections for Java 17 1Z0-829. Work through the 10 questions first, then review the explanations and return to mixed practice in IT Mastery.

PassWhat to doWhat to record
First attemptAnswer without checking the explanation first.The fact, rule, calculation, or judgment point that controlled your answer.
ReviewRead the explanation even when you were correct.Why the best answer is stronger than the closest distractor.
RepairRepeat only missed or uncertain items after a short break.The pattern behind misses, not the answer letter.
TransferReturn to mixed practice once the topic feels stable.Whether the same skill holds up when the topic is no longer obvious.

Blueprint context: 10% of the practice outline. A focused topic score can overstate readiness if you recognize the pattern too quickly, so use it as repair work before timed mixed sets.

Sample questions

These questions are original IT Mastery practice items aligned to this topic area. They are designed for self-assessment and are not official exam questions.

Question 1

Topic: Working with Arrays and Collections

A utility method should read from a wildcard source and write to a wider target. Which line can replace // INSERT so the code compiles under Java SE 17?

import java.util.*;

class Demo {
    static <T extends Number> void move(List<? extends T> src,
                                        List<? super T> dst) {
        dst.add(src.get(0));
    }

    public static void main(String[] args) {
        List<Integer> ints = List.of(5);
        List<? extends Number> source = ints;
        List<Number> target = new ArrayList<>();
        // INSERT
    }
}

Options:

  • A. Demo.<Integer>move(source, target);

  • B. Demo.<Double>move(source, target);

  • C. Demo.<Number>move(source, target);

  • D. Demo.<Number>move(source, new ArrayList<Integer>());

Best answer: C

Explanation: The explicit type witness sets the generic method type parameter before checking the arguments. Choosing Number makes the source type List<? extends Number> and the destination type List<? super Number>, both of which fit the declared variables.

Generic method invocation can use an explicit type witness, such as <Number>, to choose the method type parameter T. Here T is bounded by Number, so Number is a valid choice. With T = Number, the first parameter becomes List<? extends Number>, matching source, and the second becomes List<? super Number>, which accepts List<Number>. The method body is also valid because a value read from List<? extends T> is some subtype of T, and that value can be added to List<? super T>. The close distractors fail by choosing a type parameter that makes the wildcard source too narrow or the destination incompatible.

  • Too narrow source fails because List<? extends Number> is not safely usable where List<? extends Integer> is required.
  • Wrong destination variance fails because ArrayList<Integer> is not a List<? super Number>.
  • Double witness mismatch fails because source might hold non-Double numbers, so it cannot satisfy List<? extends Double>.

Question 2

Topic: Working with Arrays and Collections

A developer is troubleshooting this Java 17 program. It prints null:0 and then fails with ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3.

public class Monitor {
    public static void main(String[] args) {
        String[] names = new String[3];
        int[] counts = new int[3];

        names[1] = "cpu";
        counts[1] = 7;

        System.out.println(names[0] + ":" + counts[0]);
        System.out.println(names[names.length]);
    }
}

Which is the best cause or next fix?

Options:

  • A. Replace names.length with names.length().

  • B. Change the last access to names[names.length - 1].

  • C. Initialize names[0] before the first print statement.

  • D. Change new String[3] to new String[4].

Best answer: B

Explanation: The first line prints null:0 because object array elements default to null and int array elements default to 0. The exception is caused by using names.length as an index, which is outside the valid range for the array.

Java arrays have a fixed length field, and valid indexes are zero-based. For an array created with new String[3], the valid indexes are 0, 1, and 2; index 3 is invalid. The default values explain the earlier output: names[0] is null, and counts[0] is 0. To access the last element, use names[names.length - 1], not names[names.length].

Increasing the array size does not fix code that always indexes exactly at length; it just moves the invalid index.

  • Default values explain null:0, but initializing names[0] does not fix the later out-of-bounds access.
  • Larger array still fails because names[names.length] is always one past the last valid index.
  • Wrong length syntax fails because arrays use the length field, not a length() method.

Question 3

Topic: Working with Arrays and Collections

A developer is troubleshooting this Java 17 method. It must append 1 to mutable output lists declared as List<Integer>, List<Number>, or List<Object>.

import java.util.*;

class BoxDemo {
    static void addOne(List<? extends Number> values) {
        values.add(Integer.valueOf(1));  // compile error
    }
}

Changing the parameter to raw List makes the line compile but produces unchecked warnings. What is the best next fix?

Options:

  • A. Keep List<? extends Number> and cast to List<Integer>.

  • B. Change the parameter to List<?> and add the value.

  • C. Change the parameter to List<? super Integer>.

  • D. Change the parameter to raw List and suppress the warning.

Best answer: C

Explanation: List<? extends Number> is suitable for reading values as Number, but not for adding an Integer. The method’s stated job is mutation of an output list, so List<? super Integer> is the type-safe wildcard choice. Raw types and casts only hide the problem and can create heap pollution.

This is the PECS rule: use extends when a generic object produces values for you, and super when it consumes values you add. A List<? extends Number> might be a List<Double>, so adding an Integer would not be type-safe. A raw List removes generic checking, causing unchecked warnings and possible heap pollution if the wrong element type is inserted. For a method that appends an Integer to compatible destination lists, List<? super Integer> is the safe signature. You can add Integer values, but reads are only guaranteed as Object.

  • Raw suppression hides unchecked operations instead of preserving generic type safety.
  • Unchecked cast can compile but risks ClassCastException or heap pollution if the list is not really a List<Integer>.
  • Unbounded wildcard is even more restrictive for mutation; only null can be added to List<?>.

Question 4

Topic: Working with Arrays and Collections

A dashboard must sort players by team ascending, then by score descending, and then by the natural order of Player. Which statement should replace // INSERT HERE?

record Player(String team, int score, String name)
        implements Comparable<Player> {
    public int compareTo(Player other) {
        return name.compareTo(other.name);
    }
}

List<Player> players = new ArrayList<>();
// players is populated here
// INSERT HERE

Options:

  • A. players.sort(Comparator.comparing(Player::team).thenComparingInt(Player::score).reversed().thenComparing(Comparator.naturalOrder()));

  • B. Collections.sort(players);

  • C. players.sort(Comparator.comparing(Player::team).thenComparing(Comparator.comparingInt(Player::score).reversed()).thenComparing(Comparator.naturalOrder()));

  • D. players.sort(Comparator.comparing(Player::team).thenComparing(Comparator.comparingInt(Player::score)).thenComparing(Comparator.naturalOrder()).reversed());

Best answer: C

Explanation: Comparator chains are evaluated left to right, and reversed() reverses the comparator object it is called on. To keep team ascending while making only score descending, reverse the score comparator before passing it to thenComparing. The final thenComparing(Comparator.naturalOrder()) uses Player.compareTo.

The key rule is placement of reversed() in a comparator chain. Calling reversed() after thenComparingInt(Player::score) reverses the entire comparator built so far, including team. Instead, build a separate score comparator with Comparator.comparingInt(Player::score).reversed() and pass that comparator as the secondary comparison. Then thenComparing(Comparator.naturalOrder()) uses the Comparable<Player> implementation, which compares by name in the record.

This keeps the primary comparison ascending by team, changes only the secondary comparison to descending by score, and uses the record’s natural order only as the last tie-breaker.

  • Late reversal fails because calling reversed() after thenComparingInt reverses the whole team-and-score chain.
  • Final reversal fails because reversing after all comparisons reverses every comparison, including team and natural order.
  • Natural sort only fails because Collections.sort(players) uses only compareTo, so it ignores team and score.

Question 5

Topic: Working with Arrays and Collections

A task dispatcher must keep tasks in the order they should be processed. High-priority retries are added to the front, normal tasks are added to the back, and workers remove tasks from the front. Duplicate task IDs are allowed, and tasks are not retrieved by key. Which collection interface best matches these requirements?

Options:

  • A. List<Task>

  • B. Deque<Task>

  • C. Map<String, Task>

  • D. Set<Task>

Best answer: B

Explanation: The key requirement is double-ended queue behavior. A Deque preserves an order of elements and provides operations such as adding to the front or back and removing from the front, while still allowing duplicates.

In the Collections Framework, choose the interface that matches the access pattern. A Deque represents a double-ended queue, so it supports operations like addFirst(), addLast(), and removeFirst(). That directly matches the dispatcher’s need to add work at both ends and process from the front. Because duplicate task IDs are allowed, a Set is not appropriate. Because there is no lookup by key, a Map is unnecessary. A List preserves order and allows duplicates, but its primary abstraction is positional access, not queue operations at both ends.

  • List ordering is tempting because duplicates and order are allowed, but the required front/back queue operations point to Deque.
  • Set uniqueness fails because the dispatcher must allow duplicate task IDs.
  • Map lookup fails because the tasks are not retrieved by key.

Question 6

Topic: Working with Arrays and Collections

Which Java 17 standard-library rule describes a Comparator chain built with Comparator.comparing(...).thenComparing(...) when sorting a List?

Options:

  • A. A later comparator is used only after earlier comparisons return 0.

  • B. Each later comparator replaces the earlier comparator in the chain.

  • C. The last comparator in the chain is evaluated first.

  • D. The element type must implement Comparable for thenComparing().

Best answer: A

Explanation: thenComparing() builds a lexicographic comparator chain. The primary comparator decides the order unless it returns 0; only then is the next comparator used as a tie-breaker.

A Comparator chain applies comparisons in order. Comparator.comparing() defines the first sort key, and each thenComparing() adds a later tie-breaker. If an earlier comparison returns a nonzero value, that result is used immediately and later comparators are not needed for ordering those two elements. The element type itself does not need to implement Comparable when a suitable Comparator is supplied, although extracted keys may need natural ordering unless a key comparator is provided.

The key takeaway is that comparator chains sort by the first key, then by later keys only for ties.

  • Replacement misconception fails because thenComparing() adds to the comparator instead of discarding the previous comparison.
  • Reverse evaluation fails because comparator chains evaluate from the original comparator toward later tie-breakers.
  • Comparable requirement fails because supplying a Comparator can sort objects that do not define natural ordering.

Question 7

Topic: Working with Arrays and Collections

A developer writes a reusable cache. No imports are required. What is the result of compiling and running this Java 17 code?

class Cache<T> {
    private T value;

    <T> void put(T value) {
        this.value = value;
    }

    T get() { return value; }
}

public class Test {
    public static void main(String[] args) {
        Cache<String> c = new Cache<>();
        c.put("java");
        System.out.println(c.get().toUpperCase());
    }
}

Options:

  • A. It prints JAVA.

  • B. It throws ClassCastException.

  • C. Compilation fails in put due to incompatible type parameters.

  • D. Compilation fails because diamond cannot infer String.

Best answer: C

Explanation: The method declaration <T> void put(T value) introduces a new type parameter scoped to the method. That method T shadows the class T, so assigning the method parameter to the field is not type-safe for all possible type arguments.

Generic type parameters have scopes. In Cache<T>, the field value has the class type parameter. But <T> void put(T value) declares a separate method type parameter with the same name, so the parameter is not guaranteed to be the same type as the field. The compiler checks the generic class body independently of the later Cache<String> use, so this.value = value fails at compile time. If the intent is to store a Cache<T> value, the method should be declared as void put(T value) without its own <T> type parameter.

The diamond expression is valid because the target type is Cache<String>; the failure happens earlier inside the generic method body.

  • Expected output fails because the class does not compile before any println can run.
  • Runtime exception fails because this is a compile-time generic type-safety error, not a cast failure.
  • Diamond inference is valid here because new Cache<>() uses the target type Cache<String>.

Question 8

Topic: Working with Arrays and Collections

A developer is comparing loop bounds for this uneven two-dimensional array:

int[][] tasks = {
    {3, 1, 4},
    {2},
    {5, 9}
};

Assume each option uses nested for loops with row index r and column index c, and prints tasks[r][c]. Which bounds print every value exactly once without throwing an exception?

Options:

  • A. r < tasks.length and c < tasks.length

  • B. r < tasks.length and c < tasks[r].length

  • C. r <= tasks.length and c < tasks[r].length

  • D. r < tasks.length and c <= tasks[r].length

Best answer: B

Explanation: Uneven multi-dimensional arrays in Java are arrays of arrays. Each row can have a different length, so the inner loop must use tasks[r].length, not the outer array length.

Java two-dimensional arrays can be jagged: tasks.length is the number of row arrays, while tasks[r].length is the number of elements in the current row. The valid row indexes are 0 through tasks.length - 1, and the valid column indexes for a row are 0 through tasks[r].length - 1. Using <= goes one past the last valid index, and using the outer length for every row assumes a rectangular array. The key takeaway is to derive the inner bound from the current inner array.

  • Outer length as columns fails because row {2} has length 1, so column index 1 is invalid.
  • Inclusive row bound fails because row index tasks.length is one past the last row.
  • Inclusive column bound fails because column index tasks[r].length is one past the last element in that row.

Question 9

Topic: Working with Arrays and Collections

A developer says this Java 17 code compiles but fails during a test run:

import java.time.LocalDate;

public class Demo {
    public static void main(String[] args) {
        Object[] values = new String[2];
        values[0] = "OCP";
        values[1] = LocalDate.of(2025, 1, 1);
        System.out.println(values[1]);
    }
}

The failure is java.lang.ArrayStoreException: java.time.LocalDate. Which option is the best cause and fix if the array must hold both String and LocalDate objects?

Options:

  • A. Create the array with new Object[2].

  • B. Assign the LocalDate value before the String value.

  • C. Cast the LocalDate value to Object.

  • D. Declare the variable as String[] values.

Best answer: A

Explanation: Reference arrays are covariant, so a String[] can be assigned to an Object[] variable. However, the actual array object still only accepts String elements at runtime, so storing a LocalDate throws ArrayStoreException.

The core issue is the difference between the declared reference type and the runtime array type. The compiler checks values[1] = ... against the declared type Object[], so assigning a LocalDate reference is allowed. At runtime, the JVM checks the actual array object, which is a String[]. Since LocalDate is not assignment-compatible with String, the store fails with ArrayStoreException.

To store unrelated reference types such as String and LocalDate, the array object itself must be an Object[]. Changing only casts or assignment order does not change the runtime component type.

  • Assignment order does not matter because the array component type is fixed when new String[2] runs.
  • Casting to Object is unnecessary and does not make a LocalDate storable in a String[].
  • Declaring String[] would make the LocalDate assignment a compile-time error instead of fixing the runtime failure.

Question 10

Topic: Working with Arrays and Collections

What is the result of compiling and running this Java 17 code?

import java.util.*;

public class Inventory {
  public static void main(String[] args) {
    Integer[] counts = {1, 2};
    Number[] numbers = counts;

    List<Integer> intList = new ArrayList<>();
    List<Number> numberList = intList;

    numbers[0] = 3.14;
    numberList.add(4.5);
    System.out.println(numbers[0]);
  }
}

Options:

  • A. It throws ArrayStoreException at runtime.

  • B. It fails to compile at the List<Number> assignment.

  • C. It fails to compile at the Number[] assignment.

  • D. It prints 3.14.

Best answer: B

Explanation: Arrays are covariant, but generic collections are invariant. The array assignment from Integer[] to Number[] compiles, while assigning a List<Integer> to a List<Number> does not compile.

Java arrays are covariant, so an Integer[] reference can be assigned to a Number[] variable. That is why Number[] numbers = counts; is legal. Generic types are invariant, so List<Integer> is not a subtype of List<Number>, even though Integer is a subtype of Number. The compiler rejects List<Number> numberList = intList; before any runtime behavior occurs.

If the generic assignment were removed, storing 3.14 through the Number[] reference would be checked at runtime against the actual Integer[] array type.

  • Array assignment is legal because arrays are covariant.
  • Runtime exception would be possible for the array store, but compilation fails first.
  • Printed value cannot occur because the generic assignment prevents compilation.

Continue with full practice

Use the Java 17 1Z0-829 Practice Test page for the full IT Mastery route, mixed-topic practice, timed mock exams, explanations, and web/mobile app access.

Try Java 17 1Z0-829 on Web View Java 17 1Z0-829 Practice Test

Free review resource

Read the Java 17 1Z0-829 Cheat Sheet on Tech Exam Lexicon, then return to IT Mastery for timed practice.

Revised on Thursday, May 14, 2026