6.1 - Intro to Arrays

Arrays are used to store one type of data, whether it is a primitive or reference data type. Arrays themselves are reference types. They are best thought of as a list of items with a fixed size, as arrays have a set size that cannot be changed (don’t confuse this with ArrayLists which can also be thought of as a list - we’ll learn about ArrayLists in Unit 6).

Arrays are denoted by brackets {0}, with items separated by commas such as the following:

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

Before we can use arrays, we need to have an import statement, which is

import java.util.Arrays;

Making Arrays

There are two ways to make arrays: using a constructor and using a pre-initialized array.

Constructor

As with other reference types, we can initialize arrays using a constructor. However, the constructor is slightly different from the constructors from Unit 5:

dataType[] arrayName = new dataType[numberOfItems];

To create an array that holds 10 integers, we would do int[] ourArray = new int[10]; The items in the array are initialized differently depending on the data type.

We will talk about filling constructed lists in the next topic when we discuss traversing arrays.

Pre-initialized Array

We can also set an array to a pre-initialized array, similar to how we initialize strings. Here, we will initialize an array of 10 integers as follows:

int[] ourArray = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

Accessing Elements

We access elements in arrays using bracket notation as follows: arrayName[index]. The most important thing to know is that Java is a zero-indexed language, so the first item has index 0, and not 1.

Before we talk about the index of the last item, we need to discuss how to find the array length. The array length is actually an instance variable specific to that particular array denoted as arrayName.length (not to be confused with length) for Strings). Note that this is not a method, so there are no parentheses.

Therefore, the last item in the array can be accessed by using arrayName.length - 1. Do not confuse this with the constructor in which we use arrayName.length in brackets.

If we use an index outside the allowed range, we will get an ArrayIndexOutOfBoundsException. Here is a question: how do we access the even numbers in arrayOne from above?

answer

2 = arrayOne[1]
4 = arrayOne[3]
6 = arrayOne[5]
8 = arrayOne[7]
10 = arrayOne[9]

Key Terms to Remember and Review

6.2 - Traversing Arrays

Traversing an array means to access every value in the array. This is typically done using a for loop.

Forward Traversal

To traverse an array in order, you can use the following for loop:

for (int i = 0; i < array.length; i++) {
  // access or modify array elements
}

Reverse Traversal

To traverse an array in reverse order, you can use the following for loop:

for (int i = array.length - 1; i >= 0; i--) {
  // access or modify array elements
}

Limited Traversal

If you only want to traverse a portion of the array, you can specify a different start and end index. For example, to traverse from the second element to the end, you can use:

for (int i = 1; i < array.length - 1; i++) {
  // access or modify array elements
}

Subsection

You can also traverse a specific subsection of the array. For example, to traverse from the third to seventh element, you can use:

for (int i = 2; i < 7; i++) {
  // access or modify array elements
}

Examples

Here’s an example of how to double every element in an array:

public static void doubleArray(int[] array) {
  for (int i = 0; i < array.length; i++) {
    array[i] *= 2;
  }
}

While Loop

While loops can also be used to traverse an array, but for loops are more common due to their conciseness. Here’s the doubling example using a while loop:

public static void doubleArray(int[] array) {
  int i = 0;
  while (i < array.length) {
    array[i] *= 2;
    i++;
  }
}

Key Terms to Remember and Review

6.3 - Enhanced For Loops for Arrays

This is the general format for an “Enhanced For Loop” or a “for-each” loop:

for(type element : arrayName) {
	// body of the loop
}

If you want to access each element in the array without changing the values (to summarize or count them), you can access them using a for-each loop:

for (<type> <name> : <array>){
    <statement>;
    <statement>;
    
}

Here is a quick way to declare an array, and then illustrate how a for-each loop could be used to access the array:

int[] fallTemperatures = {55, 50, 59, 69, 48, 30, 48};

This initializes an array called fallTemperatures with 7 integer values.

for (int tempetures = 0; i < fallTemperatures.length; i++) {
    if (fallTemperatures[i] > 32) {
        above++;
    }
}

This is our traditional loop, which traverses the array and sums up all the temperatures that are above freezing (we assume there is a method called “above” that keeps a running count of how many days were above 32°). We can express this same process with a for-each loop:

for (int tempetures : fallTemperatures) {
    if (i > 32) {
        above++;
    }
}

with the general form of:

for (<type> <name> : <array>) {
    <statement>;
    <statement>;
    
}

Please note that for-each loops cannot modify values within an array, only examine each value in sequence. Here is another example of everything put together:

class ForEachExample {
    public static void main(String[] args) {
        int[] even_numbers = {2, 4, 6, 8};
        for(int number : even_numbers){
            System.out.println(number);
            // Output: 2, 4, 6, 8
        }
    }
}

In this example, the number variable is used to loop through the even_numbers array. For each iteration, number is assigned the value of the current element in the array, and that value is printed out.

Common Mistakes

Traversing Arrays:

Using For-Each Loops:

Remember, choosing between a traditional for-loop and a for-each loop depends on the specific requirements of your code. Each has its own use cases and advantages.

FRQ - 2015 Free Response Question #1

(A) Write a static method arraySum that calculates and returns the sum of the entries in a specified one-dimensional array. The following example shows an array arr1 and the value returned by a call to arraySum.

image

Complete method arraySum below.

/** Returns the sum of the entries in the one-dimensional array arr.
 */ 
class Sumtime {
    public static int arraySum(int[] arr) {
        int sum = 0;
        for (int num : arr) {
            sum += num;
        }
        return sum;
    }

    public static void main (String[] args) {
        int[] arr1 = {1, 3, 2, 7, 3};
        System.out.println(arraySum(arr1));
    }
}

Sumtime.main(null);
16

Example 1: Off-by-One Errors

Mistake:

int[] numbers = {1, 2, 3, 4, 5};
for (int i = 0; i <= numbers.length; i++) {
    System.out.println(numbers[i]);
}

Correction:

int[] numbers = {1, 2, 3, 4, 5};
for (int i = 0; i < numbers.length; i++) {
    System.out.println(numbers[i]);
}

Explanation: In the incorrect example, the loop tries to access numbers[numbers.length], which is out of bounds. Adjusting the loop to iterate until i < numbers.length prevents this error.

Example 2: Modifying Array Length

Mistake:

int[] numbers = {1, 2, 3, 4, 5};
numbers.length = 10; // Attempting to change the array size

Correction:

int[] numbers = {1, 2, 3, 4, 5};
int[] newNumbers = new int[10];
System.arraycopy(numbers, 0, newNumbers, 0, numbers.length);

Explanation: Since arrays in Java have a fixed size after creation, you cannot change their length. Instead, create a new array and copy the elements.

Example 3: Ignoring Returned Values

Mistake:

ArrayList<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
list.remove(2); // Ignoring the returned value

Correction:

ArrayList<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
int removedElement = list.remove(2); // Storing the returned value
System.out.println("Removed element: " + removedElement);

Explanation: The remove() method returns the element that was removed. Capturing this return value can be useful for further processing or validation.

Example 4: Modifying Elements in For-Each Loop

Mistake:

int[] numbers = {1, 2, 3, 4, 5};
for (int number : numbers) {
    number = number * 2; // This does not change the array elements
}

Correction:

int[] numbers = {1, 2, 3, 4, 5};
for (int i = 0; i < numbers.length; i++) {
    numbers[i] = numbers[i] * 2; // Correctly modifies the array elements
}

Explanation: In a for-each loop, the loop variable is a copy of the current element, not a reference. Modifications to number do not affect the array.

Example 5: Removing Elements in For-Each Loop

Mistake:

ArrayList<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
for (Integer number : list) {
    if (number % 2 == 0) {
        list.remove(number); // ConcurrentModificationException
    }
}

Correction:

ArrayList<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
Iterator<Integer> it = list.iterator();
while (it.hasNext()) {
    Integer number = it.next();
    if (number % 2 == 0) {
        it.remove(); // Safe removal during iteration
    }
}

Explanation: Modifying a collection directly during iteration can lead to concurrent modification issues. Using an Iterator and its remove() method provides a safe way to modify a collection while iterating.

image

(b) Write a static method rowSums that calculates the sums of each of the rows in a given twodimensional array and returns these sums in a one-dimensional array. The method has one parameter, a twodimensional array arr2D of int values. The array is in row-major order: arr2D[r][c] is the entry at row r and column c. The method returns a one-dimensional array with one entry for each row of arr2D such that each entry is the sum of the corresponding row in arr2D. As a reminder, each row of a two-dimensional array is a one-dimensional array. For example, if mat1 is the array represented by the following table, the call rowSums(mat1) returns the array {16, 32, 28, 20}. Assume that arraySum works as specified, regardless of what you wrote in part (a). You must use arraySum appropriately to receive full credit. Complete method rowSums below.

/** Returns a one-dimensional array in which the entry at index k is the sum of * the entries of row k of the two-dimensional array arr2D. */ 
public static int[] rowSums(int[][] arr2D)

image

(c) A two-dimensional array is diverse if no two of its rows have entries that sum to the same value. In the following examples, the array mat1 is diverse because each row sum is different, but the array mat2 is not diverse because the first and last rows have the same sum.Assume that arraySum and rowSums work as specified, regardless of what you wrote in parts (a) and (b). You must use rowSums appropriately to receive full credit. Complete method isDiverse below.

/** Returns true if all rows in arr2D have different row sums; * false otherwise. */ 
public static boolean isDiverse(int[][] arr2D)