Liang Chapter 7: Array Basics, Processing, Copying, Passing to Methods, and 2D Arrays
Array Basics
An array is a data structure that stores a fixed-size sequential collection of elements of the same type. An array is used to store a collection of data, but it is often more useful to think of an array as a collection of variables of the same type. (Liang, Ch. 7)
Declaring and Creating Arrays
To use an array in Java, you must first declare a variable to reference the array, then create the array using the new keyword. (Liang, Section 7.2)
double[] myList = newdouble[10]; // declares and creates an array of 10 doubles
Syntax
Description
dataType[] arrayName;
Declares an array variable (preferred style)
dataType arrayName[];
Declares an array variable (C-style, valid but not preferred)
arrayName = new dataType[size];
Creates the array with the given size
dataType[] arrayName = new dataType[size];
Declaration and creation in one step
dataType[] arrayName = {v1, v2, ...};
Declaration, creation, and initialization
Array Initializers
Java provides a shorthand notation, known as the array initializer, which combines declaring, creating, and initializing in one statement. (Liang, Section 7.2.4)
Array elements are accessed through the index. Array indices are 0-based: the first element is at index 0, and the last is at index arrayName.length - 1. (Liang, Section 7.2.5)
int[] arr = newint[5];
for (int i = 0; i <= 5; i++) {
arr[i] = i * 2;
}
What is the error?
A) ArrayIndexOutOfBoundsException: index 5 is out of bounds (condition should be i < 5)
B) Missing semicolon
C) Cannot multiply index by 2
The array has indices 0-4, but the loop runs up to i=5 (i <= 5). Accessing arr[5] throws ArrayIndexOutOfBoundsException. Fix: use i < 5 or i < arr.length. (Liang, Section 7.2.6)
Section Score
0 / 0
Processing Arrays
Once an array is created, you can process its elements using loops. Common operations include computing the sum, finding the maximum/minimum, random shuffling, and more. (Liang, Section 7.3)
Common Array Operations
// Sum all elementsint[] list = {4, 2, 8, 1, 5};
int sum = 0;
for (int i = 0; i < list.length; i++) {
sum += list[i];
}
System.out.println("Sum: " + sum); // Sum: 20
// Find the maximum elementint max = list[0];
for (int i = 1; i < list.length; i++) {
if (list[i] > max) {
max = list[i];
}
}
System.out.println("Max: " + max); // Max: 8
// Random shufflingfor (int i = list.length - 1; i > 0; i--) {
int j = (int)(Math.random() * (i + 1));
int temp = list[i];
list[i] = list[j];
list[j] = temp;
}
Enhanced for Loop (for-each)
Java provides an enhanced for loop (for-each) for iterating through array elements without using an index variable. (Liang, Section 7.3.7)
Use the enhanced for loop when you need to read all elements sequentially. Use a regular for loop when you need the index (e.g., to modify elements or access specific positions).
Example: Find the Largest Element (Liang, Listing 7.3 Style)
public classFindLargest {
public static voidmain(String[] args) {
double[] scores = {67.5, 89.0, 95.3, 72.1, 88.6};
double max = scores[0];
for (int i = 1; i < scores.length; i++) {
if (scores[i] > max)
max = scores[i];
}
System.out.println("The largest score is: " + max);
// Output: The largest score is: 95.3
}
}
Example: Computing Average
int[] values = {10, 20, 30, 40, 50};
int total = 0;
for (int v : values) {
total += v;
}
double average = (double) total / values.length;
System.out.println("Average: " + average); // Average: 30.0
Q1: Which loop is best for reading all array elements without needing the index?
A) while loop
B) do-while loop
C) Enhanced for loop (for-each)
D) Nested for loop
The enhanced for loop (for-each) is designed for sequentially iterating through all elements without needing an index variable. (Liang, Section 7.3.7)
Q2: When finding the max in an array, why should max be initialized to list[0] instead of 0?
A) It is faster
B) The array might contain only negative numbers
C) It prevents ArrayIndexOutOfBoundsException
D) Java requires it
If all elements are negative and max starts at 0, the result would be 0, which is incorrect. Initializing to list[0] ensures correctness for any values. (Liang, Section 7.3.2)
Trace the Code
int[] a = {1, 2, 3, 4, 5};
int result = 0;
for (int e : a) {
if (e % 2 != 0)
result += e;
}
System.out.println(result);
What is the output?
Section Score
0 / 0
Copying Arrays
Copying arrays requires care because arrays are objects in Java. Using the assignment operator copies only the reference, not the actual array contents. (Liang, Section 7.4)
Shallow Copy Pitfall
Using the assignment operator = on arrays does NOT copy the array contents. Instead, both variables point to the same array in memory. (Liang, Section 7.4)
int[] list1 = {1, 2, 3};
int[] list2 = list1; // list2 now references the SAME array as list1
list2[0] = 99;
System.out.println(list1[0]); // 99 (list1 is also affected!)
Reference vs. Value Copy
Reference copy (list2 = list1): Both variables point to the same array object. Changing one affects the other.
Value copy (using a loop, System.arraycopy, or Arrays.copyOf): Creates a new, independent array with the same values. Changes to one do not affect the other.
Copying with a Loop
int[] source = {1, 2, 3, 4, 5};
int[] dest = newint[source.length];
for (int i = 0; i < source.length; i++) {
dest[i] = source[i];
}
System.arraycopy
The System.arraycopy method provides a fast, native way to copy array elements. (Liang, Section 7.4)
The java.util.Arrays.copyOf method creates a new array by copying elements from an existing array. (Liang, Section 7.4)
import java.util.Arrays;
int[] original = {5, 10, 15};
int[] copy = Arrays.copyOf(original, original.length);
// copy is {5, 10, 15} - independent of originalint[] bigger = Arrays.copyOf(original, 5);
// bigger is {5, 10, 15, 0, 0} - padded with default values
Q1: After int[] b = a;, what happens when you change b[0]?
A) a[0] also changes because both reference the same array
B) Only b[0] changes
C) Compilation error
D) Runtime error
The assignment b = a copies the reference, not the array. Both a and b point to the same array object in memory. (Liang, Section 7.4)
Q2: What does Arrays.copyOf(arr, arr.length + 2) do?
A) Throws an exception
B) Copies only half the array
C) Creates a new array with all original elements plus 2 extra default-valued elements
D) Modifies the original array
Arrays.copyOf creates a new array of the specified length. If the new length exceeds the original, extra elements are filled with default values (0 for int). (Liang, Section 7.4)
B) backup = original copies the reference, not the array; both point to the same data
C) Arrays cannot store the value 999
The assignment backup = original makes both variables reference the same array. To create an independent copy, use a loop, System.arraycopy, or Arrays.copyOf. (Liang, Section 7.4)
Section Score
0 / 0
Passing Arrays to Methods
When an array is passed to a method, the reference of the array is passed. This means the method can modify the contents of the original array. (Liang, Section 7.5)
Pass by Reference (of the Reference)
Java passes the reference value to the method. The method receives a copy of the reference, which points to the same array object. Therefore, changes to array elements inside the method affect the original array. (Liang, Section 7.5)
public static voidfill(int[] arr, int value) {
for (int i = 0; i < arr.length; i++) {
arr[i] = value;
}
}
public static voidmain(String[] args) {
int[] nums = newint[5];
fill(nums, 7);
// nums is now {7, 7, 7, 7, 7}
}
Example: printArray Method
public static voidprintArray(int[] arr) {
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
Example: reverse Method
public static voidreverse(int[] arr) {
for (int i = 0, j = arr.length - 1; i < j; i++, j--) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
public static voidmain(String[] args) {
int[] data = {1, 2, 3, 4, 5};
reverse(data);
// data is now {5, 4, 3, 2, 1}
}
Returning Arrays from Methods
A method can return an array. The return type is declared as dataType[]. (Liang, Section 7.5)
public staticint[] createArray(int size) {
int[] arr = newint[size];
for (int i = 0; i < size; i++) {
arr[i] = i * 2;
}
return arr;
}
int[] result = createArray(4); // result is {0, 2, 4, 6}
Q1: If a method modifies an array element, does the change persist after the method returns?
A) Yes, because arrays are passed by reference
B) No, changes are local to the method
C) Only if the method returns the array
D) Only for static methods
When an array is passed to a method, the method receives the reference to the original array. Any modifications to the array elements inside the method affect the original. (Liang, Section 7.5)
Q2: What is the return type of a method that returns an int array?
A) int
B) int[]
C) Array
D) void
To return an array of integers, the method's return type must be declared as int[]. (Liang, Section 7.5)
A two-dimensional array is an array of arrays. It can be used to represent a matrix or a table of values. (Liang, Section 7.8)
Declaring and Creating 2D Arrays
// Declaration and creationint[][] matrix = newint[3][4]; // 3 rows, 4 columns// Using an initializerint[][] grid = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
Accessing Elements
Elements are accessed using two indices: matrix[row][col]. The number of rows is matrix.length and the number of columns in row i is matrix[i].length. (Liang, Section 7.8)
int[][] m = {{1, 2}, {3, 4}, {5, 6}};
System.out.println(m[0][1]); // 2 (row 0, col 1)
System.out.println(m[2][0]); // 5 (row 2, col 0)
System.out.println(m.length); // 3 (number of rows)
System.out.println(m[0].length); // 2 (columns in row 0)
Processing with Nested Loops
// Print all elements of a 2D arrayfor (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
System.out.print(matrix[i][j] + " ");
}
System.out.println();
}
Example: Sum All Elements
int[][] data = {{1, 2, 3}, {4, 5, 6}};
int total = 0;
for (int i = 0; i < data.length; i++) {
for (int j = 0; j < data[i].length; j++) {
total += data[i][j];
}
}
System.out.println("Total: " + total); // Total: 21
Ragged Arrays
In Java, each row of a 2D array can have a different length. Such arrays are called ragged arrays. (Liang, Section 7.8.3)
int[][] ragged = newint[3][];
ragged[0] = newint[2]; // row 0 has 2 columns
ragged[1] = newint[4]; // row 1 has 4 columns
ragged[2] = newint[1]; // row 2 has 1 column// Or with initializer:int[][] triangle = {
{1},
{2, 3},
{4, 5, 6}
};
Why Ragged Arrays Work
A 2D array in Java is actually an array of arrays. Each row is an independent array object, so rows can have different lengths. Use matrix[i].length (not a fixed column count) when iterating.
Q1: What does matrix.length return for a 2D array?
A) The number of rows
B) The number of columns
C) The total number of elements
D) The number of rows times columns
matrix.length returns the number of rows. To get the number of columns in row i, use matrix[i].length. (Liang, Section 7.8)
Q2: Which declaration creates a ragged array?
A) int[][] a = new int[3][3];
B) int[][] a = new int[3][];
C) int[] a = new int[3];
D) int[][] a = new int[][3];
new int[3][] creates an array of 3 rows where each row can be assigned a different-length array. Option D is invalid syntax. (Liang, Section 7.8.3)
Trace the Code
int[][] m = {{1, 2}, {3, 4}, {5, 6}};
int sum = 0;
for (int i = 0; i < m.length; i++) {
sum += m[i][0];
}
System.out.println(sum);
What is the output?
Find the Bug
int[][] matrix = newint[3][4];
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix.length; j++) {
matrix[i][j] = i + j;
}
}
What is the bug?
A) Inner loop uses matrix.length (rows=3) instead of matrix[i].length (cols=4), so column 3 is never filled
B) i + j is wrong
C) Cannot use new int[3][4]
The inner loop condition should be j < matrix[i].length (which is 4), not j < matrix.length (which is 3). This means the last column (index 3) is never accessed. (Liang, Section 7.8)