Browse Certification Practice Tests by Exam Family

Java 21 1Z0-830: Working with Arrays and Collections

Try 10 focused Java 21 1Z0-830 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 21 1Z0-830 on Web View full Java 21 1Z0-830 practice page

Topic snapshot

FieldDetail
Exam routeJava 21 1Z0-830
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 21 1Z0-830. 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

Given this Java 21 code, which statement describes the varargs behavior?

static void update(String... names) {
    names[0] = names[0].toUpperCase();
    names = new String[] { "X" };
}

public static void main(String[] args) {
    String[] data = { "ann", "bob" };
    update(data);
    System.out.println(java.util.Arrays.toString(data));
}

Options:

  • A. It prints [X].

  • B. It does not compile.

  • C. It prints [ANN, bob].

  • D. It prints [ann, bob].

Best answer: C

Explanation: A varargs parameter is treated as an array inside the method. When the caller supplies an existing array of the correct type, Java passes that same array object rather than creating a copy.

For String... names, the parameter type inside the method is String[]. Because data is already a String[], the call update(data) passes the existing array object. The assignment to names[0] changes the array element, so data[0] becomes "ANN". However, assigning names = new String[] { "X" } only changes the local parameter variable; it does not update the caller’s data reference. The key distinction is mutating the shared array object versus reassigning the local parameter.

  • Copy assumption fails because Java does not copy an existing matching array for a varargs call.
  • Reference reassignment fails because assigning names to a new array affects only the local parameter.
  • Compilation concern fails because a String[] can be passed directly to a String... parameter.

Question 2

Topic: Working with Arrays and Collections

An analyst uses an editable list of priority values. What is the result of running this code?

import java.util.*;

public class Priorities {
    public static void main(String[] args) {
        var priorities = new ArrayList<Integer>();
        priorities.add(3);
        priorities.add(1);
        priorities.add(4);
        priorities.set(1, 2);
        priorities.remove(2);
        priorities.sort(Comparator.naturalOrder());
        System.out.print(priorities.get(0) + ":" + priorities);
    }
}

Options:

  • A. 3:[3, 4]

  • B. The code does not compile because remove(2) is ambiguous.

  • C. 2:[2, 3, 4]

  • D. 2:[2, 3]

Best answer: D

Explanation: The list operations are valid, and sort orders the remaining elements in place. The decisive point is overload selection: the integer literal in remove(2) calls List.remove(int index), not remove(Object).

ArrayList supports position-based updates and retrieval through the List methods. After the three add calls, the list is [3, 1, 4]. The set(1, 2) call replaces the element at index 1, making [3, 2, 4]. Then remove(2) uses the int overload, so it removes the element at index 2, which is 4, leaving [3, 2]. Sorting in natural order changes the list to [2, 3], and get(0) retrieves 2. To remove the value 2 instead, the call would need to select remove(Object), such as by passing Integer.valueOf(2).

  • Value removal fails because remove(2) does not remove the Integer value 2 in this context.
  • No ambiguity fails because the primitive int overload is chosen directly.
  • No removal fails because remove(int index) successfully removes one element before sorting.

Question 3

Topic: Working with Arrays and Collections

A developer wants to confirm how a varargs method behaves when an existing array is passed. What is the result of compiling and running this code?

class Demo {
    static void update(String... names) {
        names[0] = "ALPHA";
        names = new String[] { "omega", "beta" };
        names[1] = "GAMMA";
    }

    public static void main(String[] args) {
        String[] data = { "alpha", "beta" };
        update(data);
        System.out.println(data[0] + ":" + data[1] + ":" + data.length);
    }
}

Options:

  • A. It prints alpha:beta:2.

  • B. It prints ALPHA:GAMMA:2.

  • C. It prints ALPHA:beta:2.

  • D. The call update(data) does not compile.

Best answer: C

Explanation: A varargs parameter is an array parameter. When an existing array of the matching element type is passed, the method receives that same array reference, so element changes before reassignment are visible to the caller.

In Java, String... names is treated inside the method as String[] names. The call update(data) is valid because data is already a String[], so no separate wrapper array is created. The assignment names[0] = "ALPHA" changes the caller’s array element. Later, names = new String[] { ... } only changes the local parameter variable to point to a different array; it does not make data point to the new array. The final assignment to names[1] affects only that new local array. The key takeaway is that array element mutation is shared, but parameter reassignment is not.

  • Copied array assumption fails because passing a matching array to a varargs parameter uses that array reference.
  • Reassignment confusion fails because assigning a new array to names does not change the caller’s data variable.
  • Invalid call claim fails because a varargs method can be invoked with either individual arguments or a compatible array.

Question 4

Topic: Working with Arrays and Collections

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

import java.util.*;

public class Demo {
    static <T extends Number> T transfer(List<? extends T> src,
                                         List<? super T> dst) {
        T value = src.get(0);
        dst.add(value);
        return value;
    }

    public static void main(String[] args) {
        List<Integer> ints = List.of(7);
        List<? super Number> out = new ArrayList<Object>();
        Number n = Demo.<Number>transfer(ints, out);
        System.out.println(n + ":" + out.size());
    }
}

Options:

  • A. It throws UnsupportedOperationException.

  • B. It does not compile because dst.add(value) is unsafe.

  • C. It prints 7:1.

  • D. It does not compile because ints is not a List<Number>.

Best answer: C

Explanation: The code compiles and prints 7:1. The explicit type witness <Number> fixes T as Number; List<Integer> is acceptable for List<? extends Number>, and List<? super Number> is acceptable for the destination.

Generic method invocation can use an explicit type witness to choose the method type parameter, as long as the chosen type satisfies its bound. Here, T is explicitly Number, which satisfies T extends Number. The source parameter is List<? extends T>, so a List<Integer> can be passed because Integer extends Number. The destination parameter is List<? super T>, so List<? super Number> can receive a Number value. Inside the method, reading from the source gives a value assignable to T, and adding a T to the lower-bounded destination is permitted. List.of(7) is not mutated; only the ArrayList destination is changed.

  • Invariant source misconception fails because the parameter is List<? extends Number>, not List<Number>.
  • Lower-bound write misconception fails because List<? super T> is specifically safe for adding values of type T.
  • Immutable source misconception fails because the immutable List.of(7) list is only read, not modified.

Question 5

Topic: Working with Arrays and Collections

Which statement is a correct Java 21 rule for java.util.Arrays utility methods?

Options:

  • A. Arrays.binarySearch(array, key) sorts the array before searching.

  • B. Arrays.asList(array) returns a fixed-size list backed by the array.

  • C. Arrays.compare(a, b) returns 0 when one array is only a prefix of the other.

  • D. Arrays.fill(array, value) replaces only null elements in the array.

Best answer: B

Explanation: Arrays.asList() creates a fixed-size list view backed by the supplied array. The list supports replacing elements but not changing its size, and element updates are shared with the original array.

The key rule is that Arrays.asList(array) does not copy elements into a resizable list. It returns a fixed-size List backed by the array, so operations such as set() are allowed, but add() or remove() throw UnsupportedOperationException. Because it is backed by the array, changing an element through the list changes the array element, and assigning an array element changes what the list sees.

The closest trap is assuming asList() behaves like new ArrayList<>(...); it does not create an independently resizable collection.

  • Binary search sorting fails because binarySearch() assumes the searched range is already sorted; it does not sort it.
  • Prefix comparison fails because Arrays.compare() treats the shorter array as smaller when all shared elements match.
  • Selective fill fails because Arrays.fill() assigns the supplied value to every element in the target range.

Question 6

Topic: Working with Arrays and Collections

Given the following Java 21 code, what is printed?

import java.util.*;

record Item(String code, int priority) implements Comparable<Item> {
    public int compareTo(Item other) { return code.compareTo(other.code); }
    public String toString() { return code + ":" + priority; }
}

public class Main {
    public static void main(String[] args) {
        var items = new ArrayList<>(List.of(
            new Item("B", 2), new Item("A", 3),
            new Item("A", 1), new Item("C", 2)));
        items.sort(Comparator.comparingInt(Item::priority)
            .thenComparing(Comparator.naturalOrder()));
        System.out.println(items);
    }
}

Options:

  • A. [A:1, B:2, C:2, A:3]

  • B. [A:3, A:1, B:2, C:2]

  • C. [A:1, A:3, B:2, C:2]

  • D. The code does not compile because naturalOrder() cannot follow comparingInt().

Best answer: A

Explanation: A comparator chain applies comparisons in the order they are chained. Here, comparingInt(Item::priority) sorts by priority first, and thenComparing(Comparator.naturalOrder()) is used only when priorities are equal.

Comparator.comparingInt(Item::priority) creates the primary ordering: ascending numeric priority. Only items with the same priority are compared by the second comparator. Comparator.naturalOrder() is valid because Item implements Comparable<Item>, and its compareTo() compares only the code value. The two items with priority 2 are therefore ordered as B:2 before C:2, while A:3 stays after all lower-priority items despite its code.

  • Natural order first fails because naturalOrder() appears only inside thenComparing(), so it is not the primary comparator.
  • Code then priority fails because no comparator in the chain sorts primarily by code and secondarily by priority.
  • Compilation failure fails because Item implements Comparable<Item>, satisfying the type requirement for Comparator.naturalOrder().

Question 7

Topic: Working with Arrays and Collections

Assume the method body is inside List<String> prepare(String[] codes). The incoming array may be unsorted. The method must sort codes in natural order and return a List<String> backed by the same array, so calling set() on the returned list updates codes. Which method body meets the requirement?

Options:

  • A. Arrays.sort(codes); return Arrays.asList(codes);

  • B. return Arrays.asList(codes);

  • C. Arrays.sort(codes); return new ArrayList<>(Arrays.asList(codes));

  • D. Arrays.sort(codes); return List.of(codes);

Best answer: A

Explanation: Arrays.sort() sorts the original array in place. Arrays.asList() then creates a fixed-size list backed by that array, so replacing an element through the list also changes the array element.

The key distinction is between a backed fixed-size list and an independent or unmodifiable list. Arrays.asList(codes) does not copy the array elements into a separate storage structure; it creates a list view backed by the array. Element replacement through set() is allowed and writes through to the array, but structural changes such as add() or remove() are not supported. Because the requirement also says the incoming array may be unsorted, Arrays.sort(codes) must run before returning the list. The option using List.of() creates an unmodifiable list that is not backed by the array, and wrapping with new ArrayList<>() creates a separate resizable copy.

  • Unmodifiable list fails because List.of(codes) is not backed by codes and does not allow set().
  • ArrayList copy fails because new ArrayList<>(...) stores elements separately from the original array.
  • Missing sort fails because returning Arrays.asList(codes) alone preserves the possible unsorted input order.

Question 8

Topic: Working with Arrays and Collections

A method builds a List<String> named work using an ArrayList. The list contains no null elements. The method must return a list that callers cannot structurally modify or replace elements in, and later changes to work must not be visible through the returned list.

Which return statement correctly applies a Java SE 21 collection rule?

Options:

  • A. return work;

  • B. return List.copyOf(work);

  • C. return Arrays.asList(work.toArray(String[]::new));

  • D. return Collections.unmodifiableList(work);

Best answer: B

Explanation: List.copyOf(work) is the best match because it returns an unmodifiable list that is not backed by the original mutable ArrayList. Since the stem states there are no null elements, it avoids the NullPointerException issue for List.copyOf().

Java collection factories and wrappers have different mutability and backing behavior. List.copyOf(collection) creates an unmodifiable list containing the current elements of the source collection; for a mutable ArrayList source, later mutations to the source are not reflected in the result. By contrast, Collections.unmodifiableList(work) prevents modification through the wrapper but remains view-backed by work, so later changes to work are visible. Arrays.asList(...) returns a fixed-size list backed by an array and still permits element replacement with set(). The key distinction is unmodifiable snapshot versus view-backed wrapper.

  • View-backed wrapper fails because Collections.unmodifiableList(work) reflects later changes made directly to work.
  • Fixed-size list fails because Arrays.asList(...) disallows size changes but permits replacing elements with set().
  • Mutable return fails because returning work gives callers the original modifiable ArrayList.

Question 9

Topic: Working with Arrays and Collections

A developer is troubleshooting this Java 21 compile error: type argument Number is not within bounds of type-variable T. The method must keep requiring comparable element types.

import java.util.*;

class Util {
    static <T extends Comparable<? super T>> T head(List<? extends T> values) {
        return values.get(0);
    }

    static void demo() {
        List<? extends Integer> counts = List.of(3, 1, 2);
        Number n = Util.<Number>head(counts);
    }
}

Which option names the best cause of the compile error?

Options:

  • A. List<? extends Integer> cannot match List<? extends T>.

  • B. The explicit witness makes T be Number, violating the bound.

  • C. values.get(0) has type Object inside the method.

  • D. The assignment target Number blocks inference of Integer.

Best answer: B

Explanation: An explicit type witness controls the method type for that invocation. Here <Number> forces T to be Number, but the method requires T extends Comparable<? super T>. Integer satisfies that bound; Number does not.

Generic method invocation type inference does not replace an explicit type witness with a better type. In Util.<Number>head(counts), T is exactly Number, so the declared bound must be checked for Number. The wildcard argument is not the problem: List<? extends Integer> can work when T is Integer. The failure is that Number does not implement Comparable<? super Number>, while Integer implements Comparable<Integer>, satisfying Comparable<? super Integer>. A valid call could use Util.<Integer>head(counts) or omit the witness and let the compiler infer a suitable type.

  • Wildcard mismatch fails because List<? extends T> is designed to accept lists whose element type is a subtype of T.
  • Target typing trap fails because assigning an inferred Integer result to Number is a valid widening reference conversion.
  • Object return trap fails because reading from List<? extends T> produces a value assignable to T, not merely Object.

Question 10

Topic: Working with Arrays and Collections

A method receives a mutable ArrayList<String> in single-threaded code. It must remove every element that starts with "tmp:" in place, without copying the list and without causing traversal-related failures. Which replacement for // TODO correctly applies the Java SE 21 traversal rule?

void clean(ArrayList<String> items) {
    // TODO
}

Options:

  • A. for (String item : items) { if (item.startsWith("tmp:")) items.remove(item); }

  • B. for (var it = items.iterator(); it.hasNext(); ) { if (it.next().startsWith("tmp:")) it.remove(); }

  • C. for (var it = items.listIterator(); it.hasNext(); ) { if (it.next().startsWith("tmp:")) items.remove(it.previousIndex()); }

  • D. items.forEach(item -> { if (item.startsWith("tmp:")) items.remove(item); });

Best answer: B

Explanation: The safe in-place removal during iterator traversal is to remove through the iterator itself. Calling Iterator.remove() after next() keeps the iterator’s internal state consistent with the collection’s structural change.

Java’s fail-fast collection traversals track structural modifications. An enhanced for loop uses an iterator internally, but it does not expose that iterator, so calling items.remove(...) modifies the backing list outside the iterator’s control. forEach over the same list has the same basic problem when its callback structurally changes the source. A ListIterator can also remove safely, but only with it.remove() after next() or previous(), not by calling items.remove(...) directly. The key rule is: during traversal, structural removal must go through the active iterator’s remove method.

  • Enhanced for removal changes the backing list outside the hidden iterator, making the traversal unsafe.
  • forEach mutation structurally modifies the source list while it is being traversed.
  • Direct ListIterator bypass uses the list’s remove method instead of ListIterator.remove(), invalidating the iterator state.

Continue with full practice

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

Try Java 21 1Z0-830 on Web View Java 21 1Z0-830 Practice Test

Free review resource

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

Revised on Thursday, May 14, 2026