One of the biggest limitations of arrays is that they have a static size - i.e. you determine the array size when initializing the array and this cannot be changed later on, for instance, to append or remove array elements as needed while the program is running.
The ArrayList objects have the following advantages over regular arrays:
they have a dynamic size - it can be changed after the array has been initialized - that is during the run-time of the program
there are ready-made getter/setter methods for inserting and deleting ArrayList elements as well as other methods, such as sorting and reversing the arrayList elements.
In order to use an arrayList in your program, you need to import the java.util library (a collection of related classes) which includes the needed definitions for this data type.
This is how you do it:
include java.util.*;
The asterisk after the dot means that you want to bring in all the different classes that the java.util library contains. You could also just import the class needed for the functionality of your arrayList:
import java.util.ArrayList;
You will not be tested on importing the needed libraries on the AP exam, but you need to do it in order to be able to run your programs.
You can declare your arrayList without stating the data type of the individual elements (in this case, it will default to the object type):
ArrayList studentRoster = new ArrayList();
The preferred way, however, of declaring your array list is to define its data type in pointed brackets:
ArrayList<String> studentRoster = new ArrayList<String>;
This is refereed to as the generic type ArrayList<E> — E being the specific data type to use. ArrayList<E> is preffered over ArrayList because it lets the compiler detect errors before run-time.
Remember, that the "E" can only be a referenced data type (object), not a primitive. If you want to create an ArrayList of integers, for instance, you must use the Integer wrapper class to wrap the primitives before using them with an ArrayList. In other words, arrayLists can only store objects, not primitives.
Here's an example of declaring and filling an ArrayList with data:
import java.util.*;
ArrayList<String> studentRoster = new ArrayList<String>();
studentRoster.add("Andy");
studentRoster.add("Anton");
studentRoster.add("Anthony");
The .add() method appends a value to the end of the array.
If I want to print the entire ArrayList, I can just use the System.out.println() method as the toString() method is already implemented to display ArrayLists in a user-friendly way:
System.out.println(studentRoster); will result in printing: " [Andy, Anton, Anthony]".
Runestone Academy: Intro to ArrayLists - please, make sure you do the Programming Challenge: FRQ Digits - it's fun, too!
For the exam, you will be given the AP CS A Java Quick Reference, which includes the methods below - this means you don't have to memorize the syntax of these:
int size() - returns the size of the ArrayList - this is the ArrayList equivalent of the .length property used with arrays.
Example: studentRoster.size();
boolean add(E obj) - adds an object to the end of the ArrayList and returns true when successful. Integer values can be inserted directly - they get converted to an Integer object automatically (this is known as autoboxing).
Examples: studentRoster.add("Tomas"); testScores.add(56);
void add(int index, E obj) - inserts an object at the given index number position of an ArrayList and shifts the existing values at and beyond the index number to the right by one place.
Example: studentRoster.add(0,"Aldyiar"); This will add "Aldyiar" at the beginning of the ArrayList and thus increases the index numbers for the other values by one.
E remove(int index) - removes the value at the given index and moves the other values as needed, so that there is no gap in the ArrayList left. Returns the value deleted.
Example: studentRoster.remove(2); This will remove "Anton" from the ArrayList and shift "Anthony" and "Tomas" by one to the left.
E get(int index) - returns the item at the given index number.
Example: studentRoster.get(2) will return "Anthony".
E set(int index, E obj) - replaces the value at the index with obj. It returns the original value at the index.
Example: studentRoster.set(3, "Tomáš") replaces the value "Tomas" with "Tomáš" and returns the original value, "Tomas".
Operation
returning the length
accessing a value
modifying a value
Arrays
arrayName.length;
value = arrayName[indexNumber];
arrayName[indexNumber] = value;
ArrayLists
arrayListName.size();
arrayListName.get(indexNumber);
arrayListName.set(indexNumber, value);
You can traverse an array list by using the following structures (R-read, W-write, A-append):
an indexed for-loop (R/W/A)
a while loop. (R/W/A)
an enhanced for-loop (R only, otherwise the ConcurrentModificationException can be thrown.)
Here is an example of a program where all three types of loops are used:
import java.util.*;
public class TestVariousLoops
{
public static void main()
{
ArrayList<Double> donations = new ArrayList<Double>();
donations.add(50.50);
donations.add(75.00);
donations.add(83.00);
donations.add(92.30);
double total = 0;
double sum = 0;
// calculating the total donation - using the indexed for-loop for access only:
for (int i=0; i < donations.size(); i++)
{
total = total + donations.get(i);
}
System.out.println("The sum of all the donations is "+total+" euros.");
// calculating the average donation - using the enhanced for-loop for access only:
for (Double donation : donations)
sum = sum + donation;
System.out.println("The average donation was "+(sum/donations.size())+" euros.");
// printing the highest donation - using the while loop for access only:
Double highest=donations.get(0);
int index=0;
while (index<donations.size())
{
if (donations.get(index)>highest);
highest=donations.get(index);
index++;
}
System.out.println("The highest donation was "+highest+" euros.");
}
}
When removing ArrayList elements, you need to be careful not to skip an element - as when you remove an element, the index numbers shift left. Consider this example:
import java.util.*;
public class TestingInventory
{
public static void main()
{
ArrayList<String> inventory = new ArrayList();
inventory.add("knife");
inventory.add("axe");
inventory.add("belt");
inventory.add("belt");
inventory.add("axe");
// removing the belts:
for (int i=0; i < inventory.size(); i++)
{
if (inventory.get(i).equals("belt"))
inventory.remove(i);
}
System.out.println(inventory);
}
}
You would expect it to print knife, axe, axe, but instead, it prints knife, axe, belt, axe. The reason why it didn't delete the second "belt" (index number 3) is because upon removing an element from an ArrayList, the index numbers of all the elements to the right of it shift left by one. This results in the loop skipping over element number 3 as upon the deletion of element number 2, the one next to it - number 3 - becomes number two. See the table below:
the ArrayList before the deletion of element no. 2:
the ArrayList after the deletion of element no. 2:
the ArrayList after the completion of the loop:
In order to overcome this problem, we need to modify the for-loop in the following way:
for (int i=0; i < inventory.size(); i++)
{
if (inventory.get(i).equals("belt"))
{
inventory.remove(i);
i--;
}
Adding the i--; statement will make sure the index readjusts to the now one-value shorter ArrayList and thus doesn't skip the value that comes after the deleted one.
Runestone Academy: CS Awesome: Unit 7.3 - make sure you do the FRQ at the end
You need to be familiar with the following algorithms in terms of using ArrayLists:
Inserting items
Deleting items
Finding the minimum or maximum value
Calculating a sum, average, or mode of the values in the array
Searching for a particular value in the array
Determining whether at least one item has a particular property
Determining whether all elements have a particular property
Accessing all consecutive (neighboring) pairs of items
Determining the presence or absence of duplicate items
Calculating the number of elements meeting specific criteria
Shifting or rotating items left or right
Reversing the order of the elements
In this example I test an arrayList of Strings (the first parameter of the hasMoreThanLetters() method) to see if each string is longer than the length stipulated in the stringLength parameter (that's the particular property I chose for this demonstration):
import java.util.*;
public class Main
{
public static void Main()
{
ArrayList<String> studentRoster = new ArrayList<String>();
studentRoster.add("Andy");
studentRoster.add("Anton");
studentRoster.add("Anthony");
System.out.println(hasMoreThanLetters(studentRoster,3));
}
public static boolean hasMoreThanLetters(ArrayList<String> arrayList, int stringLength)
{
for (String item : arrayList)
{
if (item.length()>stringLength)
return false;
}
return true;
}
}
For finding duplicates, we will create a new arrayList which will store unique values only. Then we will compare the size of the two arrayLists — if they are the same, there are no duplicates, so the method returns false. Otherwise, it means that there are duplicates and the method returns true.
We start by creating a new arrayList and then check each item from the arrayList given to see whether this item is in the new array list yet or not. If it isn't there yet, we add it using the one-parameter add() method.
To tell whether a value is contained in an arrayList or not, we created another method called isIncluded(). It returns true if a given value is included in the arrayList given, otherwise it returns false.
import java.util.*;
public class Main
{
public static void Main()
{
ArrayList<String> studentRoster = new ArrayList<String>();
studentRoster.add("Andy");
studentRoster.add("Anthony");
studentRoster.add("Anton");
studentRoster.add("Anthony");
System.out.println(hasDuplicates(studentRoster));
}
public static boolean isIncluded(String value, ArrayList<String> arrayList)
{
for (String item : arrayList)
{
if (item.equals(value))
return true;
}
return false;
}
public static boolean hasDuplicates(ArrayList<String> arrayList)
{
ArrayList<String> uniqueValues = new ArrayList<String>();
for (String item : arrayList)
{
if (!isIncluded(item, uniqueValues))
uniqueValues.add(item);
}
if (uniqueValues.size()!=arrayList.size())
return true;
return false;
}
}
The method reverseOrder() traverses through the given arrayList backwards and keeps adding elements one-by-one to the new arrayList called reversedList.
import java.util.*;
public class Main
{
public static void Main()
{
ArrayList<String> studentRoster = new ArrayList<String>();
studentRoster.add("Aldyiar");
studentRoster.add("Anthony");
studentRoster.add("Anton");
studentRoster.add("Tomas");
System.out.println(reverseOrder(studentRoster));
}
public static ArrayList<String> reverseOrder(ArrayList<String> arrayList)
{
ArrayList<String> reversedList = new ArrayList<String>();
for (int i=arrayList.size()-1;i>=0;i--)
{
reversedList.add(arrayList.get(i));
}
return reversedList;
}
}
Runestone Academy: CSAwesome: Unit 7.4 - please make sure you do all the FRQ questions.
Data lab - only do the open-ended activity, please, you will work in pairs on this (use repl.it to collaborate).
Sequential (a.k.a. linear) searching is a search algorithm where you go through the ArrayList item by item from the beginning, until you have found what you're looking for or you have reached the end of the ArrayList. It returns the index number of the item found; alternatively, it returns -1 if no match was found. Sequential search is the default search method used with magnetic tape (such as VCR cassettes, back-up tape or audio cassettes) - e.g. keep fast forwarding until you found what you were looking for.
Binary searching can be only applied to a sorted set of data. It starts from the middle of the data set to see if the value in the middle is greater or less than or equals the value we're looking for. According to the result, it then proceeds searching just the half of the ArrayList towards the beginning or towards the end of the ArrayList. Then it repeats the same steps - checks the middle of the halved ArrayList to see whether to continue searching forwards or backwards. This process repeats until the value has been found or the entire scope has been searched. Binary search is nicely explained at Geeks for Geeks. It includes examples of this search in various programming languages. It's called binary search because we keep dividing the ArrayList in two halves in the process.
The sequentialSearch() method takes two arguments - the ArrayList to search and the int value to look up. It returns the index number of the first matching value found in the ArrayList or it returns -1 if none found.
import java.util.*;
public class Searching
{
public static void main()
{
ArrayList<Integer> scores = new ArrayList();
scores.add(55);
scores.add(38);
scores.add(97);
scores.add(84);
scores.add(65);
scores.add(78);
scores.add(47);
System.out.println(sequentialSearch(scores,84));
}
public static int sequentialSearch(ArrayList<Integer> arrayList, int lookupValue)
{
for (int i=0; i<arrayList.size(); i++)
{
if (lookupValue==arrayList.get(i))
{
return i;
}
}
return -1;
}
}
import java.util.*;
public class BinarySearch
{
public static void main()
{
ArrayList<Integer> sortedScores = new ArrayList();
sortedScores.add(38);
sortedScores.add(47);
sortedScores.add(55);
sortedScores.add(63);
sortedScores.add(78);
sortedScores.add(83);
sortedScores.add(94);
System.out.println(binarySearch(sortedScores,38));
System.out.println(binarySearch(sortedScores,47));
System.out.println(binarySearch(sortedScores,55));
System.out.println(binarySearch(sortedScores,63));
System.out.println(binarySearch(sortedScores,78));
System.out.println(binarySearch(sortedScores,83));
System.out.println(binarySearch(sortedScores,94));
}
public static int binarySearch(ArrayList<Integer> arrayList, int lookupValue)
{
int middleIndex=arrayList.size()/2;
int upperBound=arrayList.size()-1;
int lowerBound=0;
while (upperBound!=lowerBound)
{
if (arrayList.get(middleIndex)==lookupValue)
return middleIndex;
else if (arrayList.get(middleIndex)<lookupValue)
lowerBound=middleIndex+1;
else
upperBound=middleIndex-1;
if (middleIndex==upperBound)
return upperBound;
middleIndex=(upperBound+lowerBound)/2;
}
return -1;
}
}
There are multiple algorithms (methods) for sorting an unsorted array/ArrayList of numerical or textual data. The two sorting algorithms you should know for the AP exam are selection sort and insertion sort. Merge sort will not be tested this year as it involves recursion.
Here's an example for an unsorted ArrayList of numerical data and an unsorted array of strings.
ArrayList<Integer> scores = new ArrayList();
scores.add(55);
scores.add(37);
scores.add(93);
scores.add(79);
String[] languages = {"C++","Python","C","Java"};
These data structures are unsorted because they are not arranged from smallest to largest. This brings about several disadvantages when trying to process such data structures; for instance, it is impossible to use the binary search algorithm or create a frequency table in a resources-efficient way. Sorting textual data alphabetically and numerical data from smallest to greatest (or the other way around) is a very common task that computers perform. Below, you can see the two data structures above after some sorting algorithm has been applied:
[37,55,79,93]
{"C","C++","Java","Python"};
In short, selection sort starts from the beginning of the array and compares element 0 to all the other elements and finds the minimum. It then swaps the minimum value with value that was at position 0, so that the minimum value appears at the beginning of the array (the swapped values appear in bold):
[3,86,-20,14,40] --> [-20,86,3,14,40]
Then it moves to position 1; it finds the minimum from position 1 onward. It then swaps the new minimum with the value at position 1:
[-20,86,3,14,40] --> [-20,3,86,14,40]
Afterwards, it moves to position 2; it finds the minimum from position 2 onward. It then swaps the new minimum with the value at position 2:
[-20,3,86,14,40] --> [-20,3,14,86,40]
It then proceeds to position 3 and finds the minimum from position 3 onward. It then swaps the new minimum with the value at position 3:
[-20,3,14,86,40] --> [-20,3,14,40,86]
It does not need to check the last item as it would be checking it with itself; the array is now sorted numerically in ascending order.
The code for selection sort, as published in the AP CS A course description, is as follows:
import java.util.Arrays;
public class SortTest
{
public static void selectionSort(int[] elements)
{
for (int j = 0; j < elements.length - 1; j++)
{
int minIndex = j;
for (int k = j + 1; k < elements.length; k++)
{
if (elements[k] < elements[minIndex])
{
minIndex = k;
}
}
int temp = elements[j];
elements[j] = elements[minIndex];
elements[minIndex] = temp;
}
}
public static void main(String[] args)
{
int[] arr1 = {3, 86, -20, 14, 40};
System.out.println(Arrays.toString(arr1));
selectionSort(arr1);
System.out.println(Arrays.toString(arr1));
}
}
My comments:
Make sure you import the util.Arrays library.
The outer loop (using j as iterator) starts from the first element (element zero) and finishes before the last one - there is no need to check the very last element with itself to see which is smaller.
minIndex holds the index of the minimum value - to begin with, it's set to the left-most element of the array subset.
The inner loop checks the minimum against all the remaining elements and if it finds a smaller one, it sets it as a new minimum.
After the inner loop has finished, it is time to swap the new minimum with the element at the j position.
Notice that this array is quite unsorted.
Notice you need to use the Arrays.toString() method to display the contents of an array.
This video introduces some of the most common sorting algorithms . You only need to watch the part discussing selection sort - up to 4:30:
Here's another very succinct explanation of selection sort, complete with pseudocode:
It checks the current value with the values to its left of it and if need be swaps the values (done with a nested while-loop). This ways it progresses throughout the array (using the outer for-loop) all the way to its end (unlike selection sort which ends at length-1).
You start from position 1 of the array (37) and compare it with position 0 (55); swap the values if necessary (all the swaps are in bold; the crossed-out values are not being examined):
[55,37,93,79,28] --> [37,55,93,79,28] // the first for loop iteration
Then it proceeds to position 2 and checks its value with that in positions 1 and 0; if need be, swapping of values occurs:
[37,55,93,79,22] --> [37,55,93,79,22] // the second for loop iteration
In this case, no swapping of values was necessary.
Then it proceeds to position 4 and checks its value with that in position 3, 2 and 1:
[37,55,93,79,22] --> [37,55,79,93,22] // the third for loop iteration
Here it only needed to swap 79 with 93, no other swaps further to the left were necessary.
Finally, in the fourth for-loop iteration it moves on to the last position - 5 and checks its value with those in the positions to its left; whenever it finds a larger value, it makes a swap:
[37,55,79,93,22] --> [37,55,79,22,93] --> [37,55,22,79,93] --> [37,22,55,79,93] --> [22,37,55,79,93]
Here it had to do four swaps before 22 got to the correct position in the array.
The array is now sorted numerically in ascending order.
The code for selection sort, as published in the AP CS A course description, is as follows:
import java.util.Arrays;
public class SortTest
{
public static void insertionSort(int[] elements)
{
for (int j = 1; j < elements.length; j++)
{
int temp = elements[j];
int possibleIndex = j;
while(possibleIndex>0 && temp < elements[possibleIndex - 1])
{
elements[possibleIndex] = elements[possibleIndex - 1];
possibleIndex--;
}
elements[possibleIndex] = temp;
}
}
public static void main(String[] args)
{
int[] arr1 = {3, 86, -20, 14, 40};
System.out.println(Arrays.toString(arr1));
insertionSort(arr1);
System.out.println(Arrays.toString(arr1));
}
}
My comments:
Don't forget to import the Arrays library.
The outer loop starts at position one and runs all the way through the elements; the increasing iterator being j.
temp is a variable for storing the current value to be able to swap it if need be.
possibleIndex is a decreasing iterator which is used to traverse the values to the left of the j position.
The while loop is the inner loop which keeps running as long as it finds smaller values to the left of the current position - the possibleIndex iterator. When it finds one that is smaller than the current value, it swaps them. When it has reached the beginning of the array, it swaps the value in the possibleIndex with the value in j position.
starts from position 0
uses two loops: both the inner and outer loop are for-loops
the size of the sub-array that is searched decreases with each outer loop iteration
ends traversing the array (in the outer loop) with the second-to-last element
the number of run-times is always the same regardless of how sorted/unsorted the array is to begin with
this algorithm will slightly outperform insertion sort in cases where the data is nearly sorted and will substantially outperform insertion sort with data sets that are reverse-sorted.
starts from position 1
uses two loops: the outer loop is a for-loop, the inner being a while loop
the size of the sub-array that is searched increases with each outer loop iteration
ends traversing the array (in the outer loop) with the last element
the number of run-times varies — it depends on how sorted/unsorted the array is to begin with (it depends on the number of the while-loop iterations)
this algorithm tends to be more efficient with data sets that are unsorted, which is the usual situation.
When it comes to ethical issues around data collection, you need to be able to "explain the risks to privacy from collecting and storing personal data on computer systems."
(AP Course and Exam Description)Computer programs may have unintended side effects - unintended consequences.
You need to understand that whenever using the computer, your personal privacy is threatened. It is your job as a programmer to safeguard personal privacy.
There can be both positive and effects on personal security of using the computer and developing software applications.
Internet content provider (ICP)
Internet service provider (ISP)
legal vs. ethical behavior
General Data Protection Regulation (GDPR)
provider, consumer, third-party
A proposed methodology for the teaching of Information Technology ethics in schools (PDF)
Computer and Information Ethics - an entry from Standford Encyclopaedia of Philosophy
The Murky Ethics of Data Gathering in a Post-Cambridge Analytica World (article)
Videos: