6.5 Lab: Array Operations and Debugging
Prerequisites: Chapter 6: Declarations, Traversal, Copying, Tools, and Multidimensional Arrays Estimated time: 35 minutes Practice environment: JDK 17+ and Bash; the reference program uses a temporary directory
You are ready to continue when: You have defined input contracts and boundary tests, completed all warm-ups, and implemented at least two exercises.
For each problem, specify valid input, empty input, null handling, and expected failures before implementing it.
Warm-up: Predict Before Running
1. Default Values and Length
int[] values = new int[3];
System.out.println(java.util.Arrays.toString(values));
System.out.println(values.length);Write the output and explain why the index 3 is not valid.
2. Reassigning an Enhanced for Variable
int[] values = {1, 2, 3};
for (int value : values) {
value *= 10;
}
System.out.println(java.util.Arrays.toString(values));Predict whether the original array changes, then rewrite it with an index loop so that the result becomes [10, 20, 30].
3. Aliasing and Copying
int[] original = {4, 5, 6};
int[] alias = original;
int[] copy = original.clone();
alias[0] = 40;
copy[1] = 50;Write what each of the three variables sees in the array and draw the two array objects and three reference variables.
4. Binary Search
If values is {7, 1, 9, 3}, does calling Arrays.binarySearch(values, 7) directly give a reliable result? Write the correct two-step call and decode a return value for a missing element.
Implementation Problems
1. In-place Reverse
Implement reverse(int[] values), without creating a second array. Requirements:
nullis explicitly rejected;- Empty arrays and single-element arrays remain unchanged;
- The middle element in arrays with odd lengths is not moved.
2. Maximum
Implement max(int[] values). The contract of this article specifies that null throws NullPointerException, and IllegalArgumentException is thrown for empty arrays. Do not use 0 as the initial maximum value, as this would result in an incorrect answer for arrays consisting entirely of negative numbers.
3. Merge Two Sorted Arrays
Implement mergeSorted(int[] left, int[] right). Use two indices to generate a new array in linear time. The caller promises that the input is sorted in ascending order; an advanced version should verify this precondition on its own.
4. Rectangular Array Transpose
Implement transpose(int[][] matrix). First reject null rows and rows of unequal lengths, then generate a new array. Test 3×4, 1×0, and an empty outer array. Transposing 1×0 produces an empty outer array that cannot retain the original column count; document this representation limit.
Debugging Exercises
The following snippets contain compile-time errors, runtime exceptions, or logic errors that compile and run. First, determine the issue, then use javac or small tests to confirm.
Compilation Error: Invalid Initializer Syntax
int[] values = new int[3]{1, 2, 3};Fix by using int[] values = {1, 2, 3}; or new int[]{1, 2, 3}.
Compilation Error: Array Length Is Not a Method
int[] values = new int[3];
System.out.println(values.length());Fix by using values.length.
Runtime Error: The Row Has Not Been Created
int[][] grid = new int[3][];
grid[0][0] = 42;The outer component grid[0] is still null. Execute grid[0] = new int[1] first.
Logical Error: Using Sorted Indices for an Old Array
int[] values = {30, 10, 20};
int[] sorted = values.clone();
java.util.Arrays.sort(sorted);
int index = java.util.Arrays.binarySearch(sorted, 30);
System.out.println(values[index]);index identifies a position in sorted, not in the differently ordered values. If you want to preserve the original position, you need to save both the value and the original index, or use an object to record it.
Reference Implementation
Complete the task independently, then compare. First, prepare a temporary directory for the complete program:
chapter6_lab_root=$(mktemp -d)
readonly chapter6_lab_root
mkdir -p "$chapter6_lab_root/out"
cd "$chapter6_lab_root"Save as ArrayLab.java:
import java.util.Arrays;
import java.util.Objects;
public class ArrayLab {
static void reverse(int[] values) {
Objects.requireNonNull(values, "values");
for (int left = 0, right = values.length - 1;
left < right;
left++, right--) {
int temporary = values[left];
values[left] = values[right];
values[right] = temporary;
}
}
static int max(int[] values) {
Objects.requireNonNull(values, "values");
if (values.length == 0) {
throw new IllegalArgumentException("empty values");
}
int result = values[0];
for (int index = 1; index < values.length; index++) {
if (values[index] > result) {
result = values[index];
}
}
return result;
}
static int[] mergeSorted(int[] left, int[] right) {
Objects.requireNonNull(left, "left");
Objects.requireNonNull(right, "right");
int[] result = new int[Math.addExact(left.length, right.length)];
int leftIndex = 0;
int rightIndex = 0;
int target = 0;
while (leftIndex < left.length && rightIndex < right.length) {
if (left[leftIndex] <= right[rightIndex]) {
result[target++] = left[leftIndex++];
} else {
result[target++] = right[rightIndex++];
}
}
System.arraycopy(left, leftIndex, result, target,
left.length - leftIndex);
target += left.length - leftIndex;
System.arraycopy(right, rightIndex, result, target,
right.length - rightIndex);
return result;
}
static int[][] transpose(int[][] matrix) {
Objects.requireNonNull(matrix, "matrix");
int columns = matrix.length == 0 ? 0 : rowLength(matrix, 0);
for (int row = 1; row < matrix.length; row++) {
if (rowLength(matrix, row) != columns) {
throw new IllegalArgumentException("not rectangular");
}
}
int[][] result = new int[columns][matrix.length];
for (int row = 0; row < matrix.length; row++) {
for (int column = 0; column < columns; column++) {
result[column][row] = matrix[row][column];
}
}
return result;
}
private static int rowLength(int[][] matrix, int row) {
if (matrix[row] == null) {
throw new IllegalArgumentException("null row: " + row);
}
return matrix[row].length;
}
public static void main(String[] args) {
int[] values = {1, 2, 3, 4, 5};
reverse(values);
System.out.println(Arrays.toString(values));
System.out.println(max(new int[]{-9, -2, -7}));
System.out.println(Arrays.toString(
mergeSorted(new int[]{1, 3, 5}, new int[]{2, 4, 6})));
System.out.println(Arrays.deepToString(
transpose(new int[][]{{1, 2, 3}, {4, 5, 6}})));
}
}javac -d out ArrayLab.java
java -cp out ArrayLabExpected Output:
[5, 4, 3, 2, 1]
-2
[1, 2, 3, 4, 5, 6]
[[1, 4], [2, 5], [3, 6]]Acceptance and Cleanup
Test edge cases with empty arrays, single-element arrays, fully negative arrays, and irregular rows. Explain why reversing only swaps half the components, why linear merging doesn't expand in a loop, and why binary search must first satisfy the sorted prerequisite. Fault diagnosis questions also require separating compile-time errors, runtime exceptions, and logical errors.
After saving the experiment records, clean up:
cd
ls -ld -- "$chapter6_lab_root"
rm -r -- "$chapter6_lab_root"Arrays organize similar values by position. The next chapter will combine names, ages, and scores into a single object, avoiding the fragile index correspondence maintained by multiple parallel arrays.