Lesson 4.10: Algorithms with ArrayLists
Lesson 4.10: Algorithms with ArrayLists
What You'll Learn
- 4.10.A: Apply standard algorithms to ArrayLists.
- Implement min, max, sum, and average over an ArrayList.
- Implement linear search and frequency count on an ArrayList.
- Build a filtered ArrayList by adding qualifying elements from a source collection.
- Apply all patterns to ArrayLists of objects using getter methods — the direct FRQ #3 pattern.
📌 Same Patterns, New Collection
Every algorithm from Lesson 4.5 (arrays) applies directly to ArrayLists — the only differences are syntax: list.get(i) instead of arr[i], list.size() instead of arr.length, and list.add() to build result collections. If you mastered 4.5, this lesson solidifies those patterns in the ArrayList context that FRQ #3 actually uses.
Min and Max
public static int findMax(ArrayList list) {
int max = list.get(0);
for (int i = 1; i < list.size(); i++) {
if (list.get(i) > max) {
max = list.get(i);
}
}
return max;
}
Initialize to list.get(0), loop from index 1, update when a larger value is found. Identical logic to the array version — only syntax changes.
Sum and Average
public static double average(ArrayList list) {
int total = 0;
for (int x : list) {
total += x;
}
return (double) total / list.size();
}
⚠️ AP Exam Trap: Integer Division
Cast before dividing: (double) total / list.size(). Both total and list.size() are ints — dividing them without a cast truncates the decimal. The cast must come before the division, not after.
Linear Search
// Does the list contain the target?
public static boolean contains(ArrayList list, int target) {
for (int x : list) {
if (x == target) {
return true;
}
}
return false;
}
// What index is the target at?
public static int indexOf(ArrayList list, int target) {
for (int i = 0; i < list.size(); i++) {
if (list.get(i) == target) {
return i;
}
}
return -1;
}
Frequency Count
public static int countAbove(ArrayList list, int threshold) {
int count = 0;
for (int x : list) {
if (x > threshold) {
count++;
}
}
return count;
}
Building a Filtered ArrayList
This pattern is uniquely suited to ArrayList — you can't do it with a fixed-size array without a two-pass approach:
// Return a new ArrayList containing only values above the threshold
public static ArrayList getAbove(ArrayList list, int threshold) {
ArrayList result = new ArrayList();
for (int x : list) {
if (x > threshold) {
result.add(x);
}
}
return result;
}
Create an empty ArrayList, loop over the source, add qualifying elements, return the result. This is the standard FRQ #3 filter pattern.
Applying to Object ArrayLists — FRQ #3 Pattern
Every FRQ #3 gives you a class and an ArrayList of objects. The algorithms look identical — just call getters instead of reading primitives:
// Given a Movie class with getTitle() and getRating() (double 0-10)
// Return all movies with rating above a threshold
public static ArrayList getHighRated(
ArrayList movies, double threshold) {
ArrayList result = new ArrayList();
for (Movie m : movies) {
if (m.getRating() > threshold) {
result.add(m);
}
}
return result;
}
// Find the highest-rated movie's title
public static String bestMovie(ArrayList movies) {
Movie best = movies.get(0);
for (int i = 1; i < movies.size(); i++) {
if (movies.get(i).getRating() > best.getRating()) {
best = movies.get(i);
}
}
return best.getTitle();
}
📌 FRQ #3 Structure
The AP exam gives you: a class definition, an ArrayList of that class, and asks you to write 1–2 methods. Those methods are always some combination of filter, count, find-max/min, or search. The class and field names change every year — the algorithm structure does not.
Summary
- All five standard algorithms (min/max, sum/average, linear search, frequency count, filter) apply to ArrayLists using
list.get(i)andlist.size(). - The filter pattern uses an empty ArrayList, adds qualifying elements, and returns the result — only possible without a two-pass because ArrayList is resizable.
- For object ArrayLists, replace primitive access with getter method calls.
- FRQ #3 is always some combination of these five patterns on an ArrayList of objects.
Practice Questions
public static int findMin(ArrayListlist) { int min = list.get(0); for (int i = 1; i < list.size(); i++) { if (list.get(i) < min) { min = list.get(i); } } return min; }
public static int mystery(ArrayListlist) { int count = 0; for (int x : list) { if (x % 2 == 0) count++; } return count; }
Product class has getPrice() returning a double. Which correctly returns the average price from an ArrayList named items?double sum = 0;
for (Product p : items) {
sum += p.getPrice();
}
return sum / items.length;
double sum = 0;
for (Product p : items) {
sum += p.getPrice();
}
return sum / items.size();
int sum = 0;
for (Product p : items) {
sum += p.getPrice();
}
return sum / items.size();
double sum = 0;
for (Product p : items) {
sum += p.getPrice();
}
return (int) sum / items.size();
items.length — ArrayList has no length field. C uses int accumulator — truncates decimal prices. D casts sum to int before dividing — loses the decimal. B correctly uses a double accumulator and items.size().Student class has getName() and getScore(). Which method correctly returns the name of the student with the highest score?Student best = roster.get(0);
for (int i = 1; i < roster.size(); i++) {
if (roster.get(i).getScore() > best.getScore()) {
best = roster.get(i);
}
}
return best.getName();
int max = 0;
for (Student s : roster) {
if (s.getScore() > max) {
max = s.getScore();
}
}
return max;
Student best = roster.get(0);
for (Student s : roster) {
if (s.getName() > best.getName()) {
best = s;
}
}
return best.getName();
for (Student s : roster) {
if (s.getScore() > 0) {
return s.getName();
}
}
return null;
Song class has getArtist() and getDuration() (int, seconds). Which method correctly returns an ArrayList of all songs longer than 3 minutes (180 seconds)?for (Song s : songs) {
if (s.getDuration() > 180) {
songs.remove(s);
}
}
return songs;
ArrayListresult = new ArrayList (); for (Song s : songs) { if (s.getDuration() < 180) { result.add(s); } } return result;
ArrayListresult = new ArrayList (); for (Song s : songs) { if (s.getDuration() > 180) { result.add(s); } } return result;
ArrayListresult = new ArrayList (); for (int i = 0; i < songs.size(); i++) { result.add(songs.get(i)); } return result;
Mastery: Algorithms with ArrayLists
Book class has getTitle(), getAuthor(), and getPages() (int). A method should return the number of books with more than 300 pages. Which implementation is correct?int count = 0;
for (Book b : books) {
if (b.getTitle() > 300) {
count++;
}
}
return count;
int count = 0;
for (Book b : books) {
if (b.getPages() > 300) {
count++;
}
}
return count;
int count = 0;
for (Book b : books) {
if (b.getPages() >= 300) {
count++;
}
}
return count;
int count = books.size();
for (Book b : books) {
if (b.getPages() <= 300) {
count--;
}
}
return count;
getTitle() (a String) and compares it to 300 — wrong getter, won't compile. C uses >= which includes exactly 300, but the problem says more than 300. D starts at total count and decrements, but uses <= 300 which also counts exactly 300 — same off-by-one error as C. B is the only one that correctly uses getPages() > 300.Employee class has getName() and getSalary() (double). Which method correctly returns an ArrayList of employees earning more than a given amount?public static ArrayListhighEarners( ArrayList staff, double amount) { ArrayList result = new ArrayList (); for (Employee e : staff) { if (e.getSalary() > amount) { result.add(e.getName()); } } return result; }
public static ArrayListhighEarners( ArrayList staff, double amount) { for (Employee e : staff) { if (e.getSalary() <= amount) { staff.remove(e); } } return staff; }
public static ArrayListhighEarners( ArrayList staff, double amount) { ArrayList result = new ArrayList (); for (Employee e : staff) { if (e.getSalary() < amount) { result.add(e); } } return result; }
public static ArrayListhighEarners( ArrayList staff, double amount) { ArrayList result = new ArrayList (); for (Employee e : staff) { if (e.getSalary() > amount) { result.add(e); } } return result; }
// Method 1 public static boolean hasNegative(ArrayListlist) { for (int x : list) { if (x < 0) return true; } return false; } // Method 2 public static boolean hasNegative(ArrayList list) { for (int x : list) { if (x < 0) return true; return false; } return false; }
return false is inside the loop body but outside the if. After checking the first element: if it's negative, returns true; otherwise, hits return false immediately — the loop ends after one iteration. Method 1 correctly places return false after the loop completes.Player class has getName() and getScore() (int). A method should return an ArrayList of names of all players with the maximum score. Which is correct?ArrayListresult = new ArrayList (); for (Player p : players) { if (p.getScore() == players.get(0).getScore()) { result.add(p.getName()); } } return result;
ArrayListresult = new ArrayList (); for (Player p : players) { result.add(p.getName()); } return result;
int max = players.get(0).getScore();
for (Player p : players) {
if (p.getScore() > max) max = p.getScore();
}
ArrayList result = new ArrayList();
for (Player p : players) {
if (p.getScore() == max) result.add(p.getName());
}
return result;
for (Player p : players) {
if (p.getScore() == players.get(0).getScore()) {
return p.getName();
}
}
return "";
Item class has getCategory() returning a String. Which method correctly returns the number of items in the "Electronics" category?int count = 0;
for (Item item : inventory) {
if (item.getCategory() == "Electronics") {
count++;
}
}
return count;
int count = 0;
for (Item item : inventory) {
if (item.getCategory().equals("Electronics")) {
count++;
}
}
return count;
int count = 0;
for (Item item : inventory) {
if (item.getCategory() = "Electronics") {
count++;
}
}
return count;
int count = 0;
for (Item item : inventory) {
if (item.getCategory().compareTo("Electronics")) {
count++;
}
}
return count;
== to compare Strings — compares references, not content, and may not work reliably. C uses a single = which is assignment, not comparison — compile error. D uses compareTo() which returns an int, not a boolean — compile error. B correctly uses .equals() for String content comparison.Get in Touch
Whether you're a student, parent, or teacher — I'd love to hear from you.
Just want free AP CS resources?
Enter your email below and check the subscribe box — no message needed. Students get daily practice questions and study tips. Teachers get curriculum resources and teaching strategies.
Message Sent!
Thanks for reaching out. I'll get back to you within 24 hours.
Prefer email? Reach me directly at [email protected]