6.2 Traversing Arrays

Using iterative statements (such as standard for loops and while loops) to traverse each element in an array.

Traversing using a for loop

  • Traversing an array means to access each element of an array.
    • Since an array is indexed from 0 to the number of elements -1, a standard for loop is a convenient way to accomplish traversal of an array.

The for loop is used to iterate over a sequence of elements. The syntax of the for loop is as follows:

for (initialization; condition; increment/decrement) {
    // code to be executed
}

forloopimage

public static void main(String[] args) {    
    int[] list = new int[5];
    for (int index =0; index < list.length; index++) {
        list[index] = (int) (Math.random() * 100);
    }
    System.out.println(Arrays.toString(list));
}
main(null);

What does the code above do?

  • A for loop can also be used to access only some of the elements in an array
public static void main(String[] args) {    
    int[] list = new int[5];
    for (int index =0; index < list.length; index+=2) {
        list[index] = (int) (Math.random() * 100);
    }
    System.out.println(Arrays.toString(list));
}
main(null);

What is the difference of between this code and the previous code? What do you think the output will look like?

For loop : Accessing Some Elements of a List

  • The for loop can be used to access only some of the elements in an array.

Odd Index only

public class oddIndexOnly {
    public static void main(String[] args) {
        int[] listOfNumbers = new int[] {1, 2, 3, 4, 5};
        for (int index=0; index<listOfNumbers.length; index+=2) {
            System.out.println(listOfNumbers[index]);
        }
    }
}
oddIndexOnly.main(null);

Even Index only

public class evenIndexOnly {
    public static void main(String[] args) {
        int[] listOfNumbers = new int[] {1, 2, 3, 4, 5};
        for (int index=1; index<listOfNumbers.length; index+=2) {
            System.out.println(listOfNumbers[index]);
        }
    }
}
evenIndexOnly.main(null);

Popcorn Hack 1

Write a method that takes an integer array as input and returns the sum of all even numbers in the array. If there are no even numbers, return 0

public static int sumOfEvenNumbers(int[] arr) {
    /* 
     * This function takes an array of integers as input and returns the sum of all even numbers in the array.
     */
    int sum = 0;
    for (int num : arr) {
        if (num % 2 == 0) {  // Check if the number is even
            sum += num;       // Add even number to sum
        }
    }
    return sum;
}

// Example usage:
int[] arr = {1, 2, 3, 4, 5};
System.out.println(sumOfEvenNumbers(arr)); // Output: 6

6

For-each loop

  • The for-each loop is used to traverse an array or a collection in Java
  • It is easier to use than a standard for loop because it eliminates the need to keep track of the loop variable.
for (type variableName : arrayName) {
    // code to be executed
}

for-eachimage

  • The for-each loop doesn’t have direct access to the index of the array elements, so it’s not possible to easily skip elements based on their index, like odd or even indices
  • Solution: Use a separate variable to keep track of the index
int[] array = {1, 2, 3, 4, 5, 6, 7};
int index = 0;

for (int num : array) {
    if (index % 2 != 0) {  // Check if index is odd
        System.out.println(num);
    }
    index++;
}

Popcorn Hack 2

Write a method that traverses an integer array and counts how many times a specific number appears. Make sure to use a for-each loop.

public static int countOccurrences(int[] arr, int target) {
    /*
     * This function takes an array of integers and a target integer as input and returns the number of times the target integer appears in the array.
     */
    int count = 0;
    for (int num : arr) {
        if (num == target) {  // Check if the current number matches the target
            count++;           // Increment the count
        }
    }
    return count;  // Return the total count of occurrences
}

// Example usage:
int[] arr = {3, 5, 3, 3, 7, 5};
int target = 3;
System.out.println(countOccurrences(arr, target)); // Output: 3

3

Traversing with a while loop

  • The while loop is used to iterate over a block of code as long as the condition is true.
  • The syntax of the while loop is as follows:
while (condition) {
    // code to be executed
}

Example of while loop

public static void main(String[] args) {    
    int[] arr = new int[5];
    int position = 0;
    while (position < arr.length) {
        arr[position] = (int) (Math.random() * 100);
        position ++;
    }
    System.out.println(Arrays.toString(arr));
}
main(null);

Does the while loop accomplish traversing the array?
Remember that traversing means to access each element of an array.

Both the while loop and the for loop perform the same task. The key difference is that after the while loop finishes, the variable index will still exist.

Popcorn Hack 3

Write a method that traverses an array of integers and returns the index of the first negative number. If there are no negative numbers, return -1. Use a while loop.

public static int firstNegativeIndex(int[] arr) {
    /*
     * This function takes an array of integers as input and returns the index of the first negative number in the array. 
     * If there are no negative numbers in the array, the function should return -1.
     */
    int index = 0;  // Initialize index to 0
    while (index < arr.length) {  // Loop until we reach the end of the array
        if (arr[index] < 0) {  // Check if the current number is negative
            return index;  // Return the index of the first negative number
        }
        index++;  // Move to the next index
    }
    return -1;  // Return -1 if no negative numbers are found
}

// Example usage:
int[] arr = {4, 7, -2, 5};
System.out.println(firstNegativeIndex(arr)); // Output: 2

2

Bound Errors

  • When using loops to access array elements, we need to be careful with the condition in order to avoid an ArrayIndexOutOfBoundsException being thrown.
int[] list = new int[5];
for (int index =0; index <= list.length; index++) {
    list[index] = (int) (Math.random() * 10);
}

Or

int[] arr = new int[5];
int position = 0;
while (position <= arr.length) {
    arr[position] = (int) (Math.random() * 10);
    position ++;
}

Here, the condition in the for loop is index <= list.length or position <= arr.length, which will cause an ArrayIndexOutOfBoundsException because the index is out of bounds when it is equal to the length of the array.

When using loops to access array elements, we also need to be sure we include all of the elements desired. It is easy to miss the first or last element, which is considered an “off by one” error.

int[] list = new int[5];
for (int index =0; index < list.length-1; index++) {
    list[index] = (int) (Math.random() * 10);
}

Or

int[] arr = new int[5];
int position = 1;
while (position < arr.length) {
    arr[position] = (int) (Math.random() * 10);
    position ++;
}

What do you think is wrong with both of these loops?

Multiple Choice Question

Consider the following code:

String[] list = {"red", "yellow", "blue"};
for (int i = 0; i < list.length; i++) {
    System.out.print(list[i].length() + "_");
}

What is displayed after the code is executed?

A. red_yellow_blue

B. 3_3_3_

C. 3_6_4_

D. 3_3_

E. 3_6_


Consider the following code segment which is intended to display every other element in numbers, beginning with the first element:

int[] numbers = {13, 33, 3, -3, -333};
for (/*missing*/) {
    System.out.print(numbers[i]);
}

Which of the following could replace /*missing code*/ to make the code work as intended?

(A) int i = 0; i < numbers. length 12; it+

(B) int i = 1; i ‹ numbers. length; i++

(C) int i = 1; i < numbers.length; i+=2

(D) int i = 0; i ‹ numbers.length; i++

(E) int i = 0; i < numbers.length; i+=2


Consider the method which is intended to reverse the order of the elements in arr.

public static void reverseArray (double [] arr) {
    for (int i = 0; i < arr.length; i++) {
        double temp = arr [i];
        arr[i] = arr[arr.length-1-i];
        arr[arr.length-1-i] = temp;
    }
}

Which of the following would fix the method so it works as intended?

(A) Change the loop condition to:

i < arr. length - 1

(B) Change the loop condition to:

i < arr.length/2

(C) Change the loop condition to:

i < arr.length/2 - 1

(D) Change lines 6 and 7 to:

arr[1] = arr[arr.length-1];

arr [arr.length-i] = temp;

(E) Change the loop body to:

arr[1] = arr[arr.length-1-1];

arr [arr.length-1-1] = arr[i];

Homework Hack

Problem Statement: Given an array of integers, write a method to find the second largest unique element in the array. If the array has fewer than two distinct elements, return -1.

import java.util.HashSet;

public static int findSecondLargest(int[] arr) {
    /*
     * This function takes an array of integers as input and returns the second largest unique element in the array. 
     * If the array has less than 2 distinct elements, the function should return -1.
     */
    HashSet<Integer> uniqueElements = new HashSet<>(); // To store unique elements

    // Add elements to the HashSet to get unique values
    for (int num : arr) {
        uniqueElements.add(num);
    }

    // If there are fewer than 2 unique elements, return -1
    if (uniqueElements.size() < 2) {
        return -1;
    }

    // Convert the HashSet to an array and sort it
    Integer[] uniqueArray = uniqueElements.toArray(new Integer[0]);
    java.util.Arrays.sort(uniqueArray); // Sort the array

    // Return the second largest element
    return uniqueArray[uniqueArray.length - 2];
}

// Example usage:
public static void main(String[] args) {
    int[] arr1 = {3, 1, 4, 1, 5, 9, 2, 6};
    System.out.println(findSecondLargest(arr1)); // Output: 6

    int[] arr2 = {10, 10, 10, 10};
    System.out.println(findSecondLargest(arr2)); // Output: -1
}


Main.main(null);
6
-1

Homework down below…

public class Main {

    public static int findSecondLargest(int[] arr) {
        // Step 1: Use a TreeSet to remove duplicates and automatically sort the elements
        Set<Integer> sortedUnique = new TreeSet<>();
        for (int num : arr) {
            sortedUnique.add(num);
        }

        // Step 2: Check if we have fewer than 2 unique elements
        if (sortedUnique.size() < 2) {
            return -1;  // If less than 2 unique elements, return -1
        }

        // Step 3: Convert the set to an array or directly access the second largest
        Integer[] sortedArray = sortedUnique.toArray(new Integer[0]);
        return sortedArray[sortedArray.length - 2];  // Second largest element is at .length-2
    }

    public static void main(String[] args) {
        int[] arr1 = {3, 1, 4, 1, 5, 9, 2, 6};
        System.out.println(findSecondLargest(arr1)); // Here it gives the output of 6

        int[] arr2 = {10, 10, 10, 10};
        System.out.println(findSecondLargest(arr2)); // and here it gives the out of -1
    }
}

Main.main(null);
6
-1