Logo

Unit 7: ArrayList

Mastering the concept of Java’s ArrayList. AP Exam weighting: 2.5-7.5%.

7.1: ArrayList Intro

Arrays ArrayLists
Fixed Length Resizable Length
Fundamental Java feature Part of a framework
An object with no methods Class with many methods
Not as flexible Designed to be very flexible
Can store primitive data Not designed to store primitives
  Slightly slower than arrays
  Need an import statement

In order to use the ArrayList class, the ArrayList class needs to be imported from the java util package. This can be done by writing import java.util.ArrayList at the top of the class file.

import java.util.ArrayList;  // Import the ArrayList class

// Declare and initialize an ArrayList of integers
ArrayList<Integer> numbersList = new ArrayList<>();

ArrayList objects are created in the same fashion as other object classes. The primary difference with ArrayLists is that the element type of the ArrayList must be specified using angled bracket <>. In this example, E represents the data type that will be used in the ArrayList. This can be replaced by an object data type:

ArrayList<E> list = new ArrayList<E>();

We can actually declare ArrayLists without specifying the type that will be included in the ArrayList, but specifying the data type is smarter because it allows the compiler to find errors before run time, so its more efficient and easy to spot errors.

ArrayList list = new ArrayList();

Quick lil popcorn hack

Create 2 ArrayLists, 1 called studentName and 1 called studentAge

public class Student
{
    public static void main(String[] args)
    {
        //Initialize your ArrayLists
        
        ArrayList<String> studentName = new ArrayList<String>();
        ArrayList<integer> studentAge = new ArrayList<integer>();
    }
}

7.2: ArrayList Methods

Learning Objectives

Students will be able to represent collections of related object reference data using ArrayList objects.

Essential Knowledge

Size of the ArrayList

Consider the following code:

ArrayList<Integer> a1 = new ArrayList<>();
System.out.println(a1.size());
0

Adding Items to an ArrayList

Consider the following code:

ArrayList<Double> a2 = new ArrayList<>();
a2.add(1.0);
a2.add(2.0);
a2.add(3.0);
a2.add(1, 4.0);
System.out.println(a2);
[1.0, 4.0, 2.0, 3.0]

Let’s Look at an Example

Consider the following code:

ArrayList<String> h = new ArrayList<>();

h.add("Hello");
h.add("Hello");
h.add("HeLLO");
h.add("Hello");
h.add(1, "Hola");

// h.add(26.2);
h.add(new String("Hello"));
// h.add(false);

System.out.println(h);
[Hello, Hola, Hello, HeLLO, Hello, Hello]

Now, consider this code:

ArrayList<String> g = new ArrayList<>();

g.add("Hello");
g.add("Hello");
g.add("HeLLO");
g.add("Hello");
g.add(1, "Hola");

g.add(new String("Hello"));

System.out.println(g);
[Hello, Hola, Hello, HeLLO, Hello, Hello]

Question: Why does this code work?

All the added elements are of the same data type

Deleting Items from an ArrayList

E remove(int index) : Removes the element at position index, and moves the elements at position index + 1 and higher to the left. It also subtracts one from the list’s size. The return value is the element formerly at position index.

// If you are confused of what list g is, look back at the previous code.
g.remove(3);
String former = g.remove(0);
System.out.println(former);
Hello

Updating Items in an ArrayList

E set(int index, E obj) : Replaces the element at position index with obj and returns the element formerly at position index.

String helloFormer = g.set(1, "Bonjour");
System.out.println(helloFormer);
System.out.println(g);
Hello
[Hola, Bonjour, Hello, Hello]

Accessing Items in an ArrayList

E get(int index) Returns the element at position index in the list.

String hello = g.get(3);
System.out.println(hello);
System.out.println(g);
Hello
[Hola, Bonjour, Hello, Hello]

Passing an ArrayList as a Method Parameter

The only time that it is wise to use ArrayList instead of ArrayList<E> is when it is as a function parameter and it is only using ArrayList<>.get(E) or ArrayList<>.size(). Consider the following code:

private void accessOnly(ArrayList arr) {
    if (arr.size() > 0) {
        System.out.println(arr.get(0)); // Change the index to the one you want to access
    } else {
        System.out.println("Array is empty");
    }
}

ArrayList<Integer> myList = new ArrayList<Integer>();
accessOnly(myList);
Array is empty

Returning an ArrayList from a Method

In order for you to return an ArrayList, the data type must be specified, and the return type must be the same as the return value. Consider the following code:

private ArrayList<String> returnTheSame() {
    ArrayList<String> arr = new ArrayList<String>(); // Initialize the ArrayList
    arr.add("Hello");
    return arr;
}

ArrayList<String> result = returnTheSame();
System.out.println(result);

[Hello]

Hacks

Hack Helper

import java.util.ArrayList;

public class ArrayListMethodsExample {
    private ArrayList<String> shoppingList = new ArrayList<>();

    private String manipulateList(String item1, String item2, int remove, int replace, String replaceItem) {
        
        //initialize some values
        shoppingList.add("strawberries");
        shoppingList.add("water");
        shoppingList.add("flour");
        shoppingList.add("cheese");
        
        // Add 2 items to the list.
        shoppingList.add(item1);
        shoppingList.add(item2);

        // Remove an item from the list anywhere of the user's choice.
        String removedItem = shoppingList.remove(remove);

        // Replace an item anywhere in the list of the user's choice.
        String replacedItem = shoppingList.set(replace, replaceItem);

        // Get the first and last element of the list
        String firstItem = shoppingList.get(0);
        String lastItem = shoppingList.get(shoppingList.size() - 1);

        // Return the items added, removed, replaced, and the list's size, in one string
        return "Added: " + item1 + ", " + item2 + "\n" +
               "Removed: " + removedItem + "\n" +
               "Replaced: " + replacedItem + " at index " + replace + "\n" +
               "First Item: " + firstItem + "\n" +
               "Last Item: " + lastItem + "\n" +
               "List Size: " + shoppingList.size();
    }

    public static void main(String[] args) {
        ArrayListMethodsExample example = new ArrayListMethodsExample();

        // Sample inputs for the method
        String list = example.manipulateList("milk", "chocolate", 0, 0, "butter");
        System.out.println(list);
    }
}


ArrayListMethodsExample.main(null)

Added: milk, chocolate
Removed: strawberries
Replaced: water at index 0
First Item: butter
Last Item: chocolate
List Size: 5

7.3: Traversing Arraylists

Learning Objectives:

Essential Knowledge:

import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        ArrayList<String> roster = new ArrayList<>();
        roster.add("Hello");
        roster.add("World");
        roster.add("Java");
        
        int sum = 0;
        for (int i = 0; i < roster.size(); i++) {
            String element = roster.get(i);
            if (element != null) {
                sum += element.length();
            }
        }
        System.out.println(sum);
    }
}


Breakdown:

Loop Conditions:

First, there are three major parts of a for loop: Initialisation, in which you declare the index, can be modified to change where you want to traverse from.

Boolean condition, in which you declare the stop condition, can be modified in order to change the index you want to stop traversing in.

Update, in which you declare how many indexes to go through, can be modified to skip certain indicies and traverse in a certain direction.

Practice:

Suppose we have an arraylist named grades, and we want to remove the entries that are lower than 70. replace the question marks with code to solve the problem:

import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        ArrayList<Double> grades = new ArrayList<>(); // Fix the arraylist
        grades.add((double)68.9);
        grades.add((double)71); // Casting
        grades.add((double)100);
        grades.add((double)80);
        for(int i = 0; i < grades.size(); i++ ){
            if(grades.get(i)<70){
                grades.remove(i);
            }
        }
        System.out.println(grades);
    }
}
Main.main(null)
[71.0, 100.0, 80.0]

Using Enhanced For-Loop With Traversing:

import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<String> roster = new ArrayList<>();
        roster.add("Hello");
        roster.add("World");
        roster.add("Java");

        // Using an enhanced for loop to iterate through the ArrayList
        for (String element : roster) {
            System.out.println(element);
        }
    }
}

Common mistakes:

Hacks:

You are going on a rollercoaster ride at Six Flags. You see that there is a height limit on one of the rides. You ask the worker and they say they create a cap on the heights because people who are too tall will get their heads cut off. Therefore, the worker must check to see that all riders are below 6 foot (72 inches). Thus, we want to remove all the heights that are equal to 72 or taller. However, if the riders are too short, they will fall out and die. We must also check that all riders are taller than 4 feet (48 inches).

import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        ArrayList<Double> heights = new ArrayList<>(); // Fix the arraylist
        heights.add((double)43);
        heights.add((double)89); 
        heights.add((double)59);
        heights.add((double)58);
        heights.add((double)81);
        heights.add((double)47);
        heights.add((double)39);
        heights.add((double)98);
        heights.add((double)85);
        heights.add((double)54);
        heights.add((double)60);
        for(int i = 0; i < heights.size(); i++ ){
            if(heights.get(i)>71 || heights.get(i)<48){
                heights.remove(i);
            }
        }
        System.out.println(heights);
    }
}
Main.main(null)
[89.0, 59.0, 58.0, 47.0, 98.0, 54.0, 60.0]

7.4: Developing Algorithms Using ArrayLists

Learning Objectives

In the context of ArrayList objects, this module aims to teach the following skills:

a. Iterating through ArrayLists using for or while loops.

b. Iterating through ArrayLists using enhanced for loops.

In the realm of algorithms, within the context of specific requirements that demand the utilization of ArrayList traversals, students will be able to:

Essential Knowledge

Popcorn Hacks:

Before you uncomment the code and run it, guess what the code will do based on what you’ve learned.

It will find the max

Let’s Look at an Example (Example 1)

public class ArrayListExample {
    private double findMax(double[] values) {
        double max = values[0];
    
        for (int index = 1; index < values.length; index++) {
           if (values[index] > max) {
               max = values[index];
           }
        }
    
        return max;
    }
    
    public static void main(String[] args) {
        double[] nums = {1.0, 3.0, 2.0, 2.0, 1.0, 69.0, 2.0, 4.0, 6.0, 2.0, 5.0, 10.0};
        ArrayListExample example = new ArrayListExample();
        double max = example.findMax(nums);
        System.out.println("Maximum value: " + max);
    }
}

ArrayListExample.main(null);
Maximum value: 69.0

Take a closer look at the findMax() method. It takes in a list of doubles as parameters. It will then use a for loop to find the maximum value in the list. Now, using what we know, can we replace the list of doubles with an ArrayList of Doubles? We sure can! Take a look at how we can use ArrayList to do just that:

public class ArrayListExample {
    private double findMax(ArrayList<Double> values) {
        double max = values.get(0);
    
        for (int index = 1; index < values.size(); index++) {
           if (values.get(index) > max) {
               max = values.get(index);
           }
        }
    
        return max;
    }
    
    public static void main(String[] args) {
        ArrayList<Double> nums = new ArrayList<>();
        nums.add(1.0);
        nums.add(3.0);
        nums.add(2.0);
        nums.add(2.0);
        nums.add(1.0);
        nums.add(69.0);
        nums.add(2.0);
        nums.add(4.0);
        nums.add(6.0);
        nums.add(2.0);
        nums.add(5.0);
        nums.add(10.0);
        
        ArrayListExample example = new ArrayListExample();
        double max = example.findMax(nums);
        System.out.println("Maximum value: " + max);
    }
}

ArrayListExample.main(null);
Maximum value: 69.0

Let’s Look at an Example (Example 2)

Take a look at this code:

public class ArrayListExample {
    private int findMin(int[] values) {
        int min = Integer.MAX_VALUE;
        for (int currentValue : values) {
           if (currentValue < min) {
               min = currentValue;
           }
        }
        return min;
    }

    public static void main(String[] args) {
        int[] nums = {420, 703, 2034, 582, 1047, 4545};
        ArrayListExample example = new ArrayListExample();
        int min = example.findMin(nums);
        System.out.println("Minimum value: " + min);
    }
}

ArrayListExample.main(null);
Minimum value: 420

Now, can we use ArrayLists to make this code better? We sure can! Take a look at the new and improved code that uses ArrayLists:

public class ArrayListExample {
    private int findMin(ArrayList<Integer> values) {
        int min = Integer.MAX_VALUE;
        for (int currentValue : values) {
           if (currentValue < min) {
               min = currentValue;
           }
        }
        return min;
    }

    public static void main(String[] args) {
        ArrayList<Integer> nums = new ArrayList<>();
        nums.add(420);
        nums.add(703);
        nums.add(2034);
        nums.add(582);
        nums.add(1047);
        nums.add(4545);
        ArrayListExample example = new ArrayListExample();
        int min = example.findMin(nums);
        System.out.println("Minimum value: " + min);
    }
}

ArrayListExample.main(null);
Minimum value: 420

Hacks

ArrayList<Integer> nums = new ArrayList<>();
        nums.add(420);
        nums.add(703);
        nums.add(2034);
        nums.add(582);
        nums.add(1047);
        nums.add(4545);

System.out.println(nums);

nums.add(69); 
nums.remove(1);  

System.out.println(nums);
[420, 703, 2034, 582, 1047, 4545]
[420, 2034, 582, 1047, 4545, 69]

Hack Helper

public class ArrayListHacks {
    private int findSum(ArrayList<Integer> values) {
        int sum = 0;
        for (int value : values) {
            sum += value;
        }
        return sum;
    }

    public static void main(String[] args) {
        ArrayList<Integer> nums = new ArrayList<>();
        nums.add(0);
        nums.add(1);
        nums.add(2);
        nums.add(3);
        nums.add(5);
        nums.add(8);

        ArrayListHacks hacks = new ArrayListHacks();
        int sum = hacks.findSum(nums);

        System.out.println("The sum of the elements in the ArrayList is: " + sum);
    }
}

ArrayListHacks.main(null);
The sum of the elements in the ArrayList is: 19

7.5 Searching

Learning Objectives

Essential Knowledge:

Search Process

Searching Linear Structures

Finding information with a computer is something we need to know how to do. Linear search algorithms are BEST used when we do not have any idea about the order of the data and so we need to look at each element to determine if what we are looking for is in fact inside the array or ArrayList.

When searching, we do need to remember that different data types require comparisons!

Searching an ArrayList of Double

public int where(double magicNumber, ArrayList<Double> realNumbers, double delta)
{
    for (int index = 0; index < realNumbers.size(); index++)
    {
        if (Math.abs(magicNumber - realNumbers.get(index)) < delta)
        {
            return index;
        }
    }
    return -1;
}

Explanation

The where function searches through a list of numbers to find and return the position of the first number that is very close to a specific target number, known as magicNumber. If no number in the list is close enough to the target number, the function returns -1, indicating that no match was found.

Searching an ArrayList of book for a String

public int findTheWord(String searchedPhrase, ArrayList<Book> myBooks)
{
    for (int index = 0; index < myBooks.size(); index++)
    {
        Book currentBook = myBooks.get(index);
        String currentPhrase = currentBook.getDescription();
        if(currentPhrase.equals(searchedPhrase))
        {
            return index;
        }
    }
    return -1;
}

Explanation

This little code snippet is like a treasure hunt through a collection of books; it’s on a mission to find the one book whose description matches exactly with a special phrase you’re looking for. If it finds the perfect match, it’ll excitedly tell you where it is in the collection, but if not, it’ll sadly let you know with a -1 that the search was a bust.

Questions

Should we use == when looking for an Object?

No, that only will return true if the variable and the element stored at that index point to the same memory, are aliases of each other

Why did we subtract the double values?

To make sure that the lack of preciosin that is inherit in the data type is handled within our code

Why does order sometimes matter?

When searching for a value to remove from a list, if we search forward we have to make sure to adjust the loop control variable, or we might skip what we are looking for when removing!

7.6 Sorting

Learning Objectives

Essential Knowledge:

Selection Sort

This is one of the easiest sorts to demonstrate. The selection sort identifies either the maximum or minimum of the compared values and iterates over the structure checking if the item stored at the index matches that condition, if so, it will swap the value stored at that index and continue. This implementation uses a helper method to perform the swap operation since variables can hold only one value at a time!

Example:

// with normal arrays
for (int outerLoop = 0; outerLoop < myDucks.length; outerLoop ++)
{
    int minIndex = outerLoop;
    for (int inner = outerLoop +1; inner < myDucks.length; inner++)
    {
        if (myDucks[inner].compareT(myDucks[minIndex]) < 0)
        {
            minIndex = inner;
        }
    }
    if (minIndex != outerLoop)
    {
        swapItems(minIndex, outerloop, myDucks);
    }
}

// with array lists
for (int outerLoop = 0; outerLoop < myDucks.size(); outerLoop++) {
    int minIndex = outerLoop;
    for (int inner = outerLoop + 1; inner < myDucks.size(); inner++) 
    {
        if (myDucks.get(inner).compareT(myDucks.get(minIndex)) < 0) 
        {
            minIndex = inner;
        }
    }
    if (minIndex != outerLoop) {
        swapItems(minIndex, outerLoop, myDucks); 
    }
}
/*
This code performs a selection sort on the myDucks ArrayList, ordering its elements based on the compareT method. 
During each iteration of the outer loop, it finds the index of the minimum element in the unsorted portion of the list and swaps it with the first element of the unsorted portion.
 */ 

Insertion Sort Algorithm

The insertion sort is characterized by building a sorted structure as it proceeds. It inserts each value it finds at the appropriate location in the data structure. This is often accomplished by using a while loop as the inner loop.

Example:

for (int outer = 1; outer < randomList.size(); outer++)
{
    DebugDuck tested = randomList.get(outer);
    int inner = outer -1;

    while ( innter >= 0 && tested.compareTo(randomList.get(inner)) < 0)
    {
        ramdomList.set(inner +1, randomList.get(inner));
        inner--;
    }
    randomList.set(inner +1, tested)
}
// This code arranges a list of DebugDuck objects in order using the insertion sort method, 
// by moving through the list and putting each item in its proper place one by one.

7.7: Ethical Issues around Data Collection

Learning Objectives:

Essential Knowledge:

Privacy Protection:

Hacks:

Grading: