Unit 4 Data Collections in AP Computer Science A (Java): Arrays, ArrayLists, and 2D Arrays
What “Data Collections” Are and Why You Use Them
In Java, a data collection is any structure that lets you store many values and work with them as a group. If you only ever needed one test score, one name, or one sensor reading, a single variable would be enough. But most real programs deal with sets of related data: all scores in a class, all items in a shopping cart, all pixels in an image, all seats in a theater.
Data collections matter because they change how you design programs:
- They let you write general solutions. Instead of 30 separate variables (
score1,score2, …), you use one collection and loops. - They help you model the real world. A classroom has a list of students, not a fixed number of student variables.
- They unlock standard algorithms: traverse, count, filter, search, sort, and aggregate.
In AP Computer Science A, the key “data collections” are:
- Arrays: fixed-size, indexed storage of elements of one type.
- ArrayLists: resizable, indexed lists (from the Java Collections Framework).
- Often (and commonly tested in the course overall), 2D arrays: grid-like arrays of arrays.
A unifying idea across all of them is index-based access: you refer to elements by position (0, 1, 2, …). If you master indexing and traversal patterns, you can solve most “data collections” problems.
Values vs. references (why collections behave “differently”)
Arrays, ArrayLists, and 2D arrays are all objects in Java, which means variables store references to them (a kind of “address”), not the entire collection itself.
This matters when you assign or pass collections:
int[] a = {1, 2, 3};
int[] b = a; // b refers to the same array as a
b[0] = 99;
System.out.println(a[0]); // prints 99
You didn’t copy the array—you copied the reference. This is called aliasing: two variables “alias” the same object.
That behavior is a common source of bugs, but it’s also powerful: you can write methods that modify a collection and see the changes outside the method.
Exam Focus
- Typical question patterns
- Predict output when arrays/ArrayLists are assigned to new variables (aliasing).
- Trace a loop that traverses a collection and updates values.
- Choose an appropriate structure (array vs. ArrayList) for a scenario.
- Common mistakes
- Assuming
b = a;copies all elements (it does not). - Forgetting that collections are objects, so changes inside a method can affect the caller.
- Mixing up “length” (arrays) and “size” (ArrayLists).
- Assuming
Arrays: Fixed-Size, Indexed Collections
An array is an object that stores a fixed number of elements, all of the same type, in a single indexed structure. You use arrays when:
- You know the number of elements won’t change (or you’re okay with creating a new array if it does).
- You need fast index-based access.
- You want a simple structure with minimal overhead.
Core properties of arrays
- Fixed size: once created, the size cannot change.
- 0-based indexing: the first element is at index
0, last is at indexlength - 1. - Homogeneous type: an
int[]can only storeintvalues; aString[]can only storeStringreferences. - Direct access:
arr[i]refers to the element at indexi.
Creating arrays
There are two common ways to create an array.
1) Create an empty array with a length
int[] scores = new int[5];
This creates an array with 5 int elements. Because it’s “empty,” Java fills it with default values:
intdefaults to0doubledefaults to0.0booleandefaults tofalse- reference types (like
String) default tonull
Example:
String[] names = new String[3];
System.out.println(names[0]); // prints null
A big idea: new String[3] creates the array, but not the String objects. Each element starts as null until you assign a real string.
2) Create and initialize with an array initializer
int[] scores = {90, 85, 100};
This creates an array of length 3 with those values.
Accessing and updating elements
You use bracket notation:
int x = scores[1]; // read
scores[1] = 88; // write
If you use an index outside 0 to length - 1, Java throws an ArrayIndexOutOfBoundsException.
length (arrays) is a field, not a method
Arrays use .length (no parentheses):
int n = scores.length;
This differs from String.length() and ArrayList.size()—a frequent source of small but costly errors.
Arrays and references (aliasing in practice)
Because arrays are objects, this is aliasing:
int[] a = {1, 2, 3};
int[] b = a;
b[2] = 10;
System.out.println(a[2]); // 10
If you truly need an independent copy, you must copy elements into a new array (often via a loop). On the AP exam, you’re commonly expected to reason about aliasing even if you don’t use advanced copying utilities.
Worked example: building and updating an array
Suppose you want to curve all scores by adding 5 points, but not exceeding 100.
Step-by-step reasoning:
- You need to update each element.
- That means you must visit each index.
- You also must cap values at 100.
int[] scores = {96, 70, 100, 88};
for (int i = 0; i < scores.length; i++) {
scores[i] = Math.min(100, scores[i] + 5);
}
// scores is now {100, 75, 100, 93}
What goes wrong most often with arrays
- Off-by-one errors: using
i <= arr.lengthinstead ofi < arr.length. - Using
.length(): arrays use.length. - Forgetting defaults: assuming
new String[3]contains empty strings; it containsnull.
Exam Focus
- Typical question patterns
- Trace array creation, default values, and updates using index-based loops.
- Identify which indices are valid and whether an exception occurs.
- Predict output from array aliasing.
- Common mistakes
- Using
<=in loop bounds, causing out-of-bounds access. - Confusing
.lengthwith.length()or.size(). - Assuming a newly created object array has real objects instead of
nullreferences.
- Using
Traversing Arrays and Writing Array Algorithms
Knowing how to create an array is only the beginning. The real power comes from traversal—systematically visiting elements to compute something or change the array.
Why traversal patterns matter
Most AP CSA collection problems reduce to one of these tasks:
- Compute a total/average
- Find a maximum/minimum
- Count items matching a condition
- Replace or transform elements
- Compare neighboring elements
- Detect a pattern (increasing sequence, duplicates, etc.)
If you can recognize which traversal pattern fits, you can write correct code faster and avoid common index errors.
Standard index-based traversal
The most common traversal uses a for loop:
for (int i = 0; i < arr.length; i++) {
// use arr[i]
}
This pattern is ideal when:
- You need the index (for example, comparing
arr[i]toarr[i - 1]). - You need to update values (
arr[i] = ...). - You want to traverse only part of the array.
Enhanced for loop (for-each) for arrays
Java also provides an enhanced for loop:
for (int x : arr) {
// x is the value of the next element
}
This is best when you only need to read elements. A subtle but important point: for primitives like int, the loop variable x is a copy of the element value. Changing x does not change the array.
int[] a = {1, 2, 3};
for (int x : a) {
x = x * 2;
}
System.out.println(a[0]); // still 1
If the array stores references to mutable objects, you can mutate the object through the reference, but you still can’t replace which object is stored at that index using the loop variable.
Common array algorithms (with explanations)
Below are core algorithm types you should be able to write and trace.
1) Accumulation (sum, total, average)
You keep a running total.
Key idea: initialize an accumulator variable before the loop, then update it for each element.
int[] nums = {2, 4, 6};
int sum = 0;
for (int i = 0; i < nums.length; i++) {
sum += nums[i];
}
// sum is 12
What goes wrong:
- Initializing
suminside the loop resets it every iteration. - Dividing integers when you meant to compute a decimal average (you may need
double).
2) Find maximum/minimum
You track the “best so far.”
Key idea: initialize using the first element (when the array is non-empty), then compare.
int[] nums = {5, 1, 9, 3};
int max = nums[0];
for (int i = 1; i < nums.length; i++) {
if (nums[i] > max) {
max = nums[i];
}
}
// max is 9
What goes wrong:
- Starting
maxat0fails if all numbers are negative. - Starting the loop at
0works but is redundant; starting at1avoids comparing the first element to itself.
3) Counting with a condition
You count elements that satisfy a test.
int[] nums = {3, 10, 7, 10};
int count10 = 0;
for (int x : nums) {
if (x == 10) {
count10++;
}
}
// count10 is 2
What goes wrong:
- Using
=instead of==(Java won’t allow it in anifcondition for primitives, but students still get confused).
4) Filtering and building a result (often needs a second structure)
Arrays can’t resize, so “filtering” often means either:
- Create a new array (if you know the size), or
- Use an
ArrayList(more flexible), or - Modify in place with careful shifting (harder).
On the AP exam, you might be asked to remove values from an array by shifting left and tracking the “logical size.” That requires careful index reasoning.
5) In-place replacement (map/transform)
You overwrite each element using its old value.
int[] nums = {1, 2, 3};
for (int i = 0; i < nums.length; i++) {
nums[i] = nums[i] * nums[i];
}
// nums is now {1, 4, 9}
Worked example: shifting (a classic index trap)
Suppose you want to delete the element at index k from an array, shifting elements left. Because arrays can’t change size, you typically shift and then treat the last spot as “unused.”
Example:
- Start with
{4, 8, 2, 7} - Delete index
1(value8) - Shift left from index
1
int[] a = {4, 8, 2, 7};
int k = 1;
for (int i = k; i < a.length - 1; i++) {
a[i] = a[i + 1];
}
// a is now {4, 2, 7, 7}
The last value is duplicated because you overwrote positions but didn’t “remove” the last slot (you can’t). In many AP-style problems, you would also keep a separate variable like size to represent how many elements are still considered valid.
Exam Focus
- Typical question patterns
- Write or trace loops that compute sums, counts, max/min, or replacements.
- Determine whether an enhanced for loop correctly updates the collection.
- Trace shifting logic for insertion/removal-like behavior.
- Common mistakes
- Trying to modify array contents via the enhanced for loop variable.
- Incorrect loop bounds when comparing
arr[i]andarr[i + 1]. - Forgetting arrays can’t shrink, so “remove” requires shifting and/or tracking logical size.
ArrayLists: Resizable Lists with Index-Based Operations
An ArrayList is a resizable, ordered list of elements from the Java standard library (java.util). It behaves a lot like an array in that you can access elements by index—but it can grow and shrink as you add or remove items.
ArrayLists matter because many real problems involve collections whose size changes: a to-do list, a playlist, customers waiting in a queue, or items in a cart. In AP CSA, ArrayLists also show up often in free-response questions because they let you practice traversal and modification without worrying about fixed sizes.
Key properties of ArrayLists
- Resizable: it can grow/shrink automatically.
- 0-based indexing: same indexing rules as arrays.
- Holds objects, not primitives: you store
Integer, notint;Double, notdouble. - Shifting behavior: adding/removing at an index shifts later elements.
Declaring and creating an ArrayList
You must import it and specify a type parameter (the element type).
import java.util.ArrayList;
ArrayList<String> words = new ArrayList<String>();
Common AP CSA style allows (and you should recognize) the diamond operator:
ArrayList<String> words = new ArrayList<>();
Wrapper classes and autoboxing
Because ArrayLists store objects, Java uses wrapper classes for primitives:
int↔Integerdouble↔Doubleboolean↔Boolean
With autoboxing, Java automatically wraps/unwraps in many cases:
ArrayList<Integer> nums = new ArrayList<>();
nums.add(5); // autoboxes int -> Integer
int x = nums.get(0); // unboxes Integer -> int
A misconception to avoid: autoboxing makes the code look like primitives are stored directly, but they are still objects under the hood.
Essential ArrayList methods (you must know these)
Assume ArrayList<E> list.
list.size()→ number of elementslist.get(i)→ element at indexilist.set(i, value)→ replace element at indexiand return the old valuelist.add(value)→ append to endlist.add(i, value)→ insert at indexi, shifting rightlist.remove(i)→ remove at indexi, shifting left, returning removed element
These are the building blocks for almost every AP CSA ArrayList question.
Shifting: the hidden behavior behind add and remove
Understanding shifting prevents a lot of index bugs.
If you insert at index 0:
ArrayList<String> a = new ArrayList<>();
a.add("A");
a.add("B");
a.add(0, "X");
// list is now ["X", "A", "B"]
If you remove at index 1:
a.remove(1);
// list is now ["X", "B"]
Elements after the insertion/removal move to keep indices contiguous.
Traversing ArrayLists
There are three common traversal styles.
1) Standard forward index loop
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
Use this when you need indices or you might call set.
2) Enhanced for loop
for (String s : list) {
System.out.println(s);
}
Use this for read-only traversal.
Be cautious: modifying the list structure (adding/removing) during an enhanced for loop is not allowed and typically causes a runtime error.
3) Backward index loop (especially for removals)
When you remove items while traversing, going backward avoids skipping elements.
Removing while traversing (the biggest ArrayList trap)
If you remove an element at index i while going forward, all later elements shift left. If you then increment i, you skip the new element that shifted into position i.
Example problem: remove all "hi" strings.
Incorrect (skips some):
for (int i = 0; i < list.size(); i++) {
if (list.get(i).equals("hi")) {
list.remove(i);
}
}
Correct approaches:
1) Traverse backward:
for (int i = list.size() - 1; i >= 0; i--) {
if (list.get(i).equals("hi")) {
list.remove(i);
}
}
2) Traverse forward, but only increment when you do not remove:
int i = 0;
while (i < list.size()) {
if (list.get(i).equals("hi")) {
list.remove(i);
} else {
i++;
}
}
A very common overload pitfall: remove(int) vs remove(Object)
For ArrayList<Integer>, remove is tricky because int can mean an index.
ArrayList<Integer> nums = new ArrayList<>();
nums.add(10);
nums.add(20);
nums.add(10);
nums.remove(10); // tries to remove index 10 (crash if size < 11)
To remove the value 10, you need to pass an Integer object:
nums.remove(Integer.valueOf(10));
This is a classic AP CSA “why did this crash?” or “what does this do?” question.
Exam Focus
- Typical question patterns
- Trace code using
add,add(index, ...),remove,set,get, and shifting effects. - Write loops that modify an ArrayList (remove/filter/replace).
- Explain or fix a bug involving
removeonArrayList<Integer>.
- Trace code using
- Common mistakes
- Using
.lengthinstead of.size(). - Removing while traversing forward and unintentionally skipping elements.
- Modifying an ArrayList inside an enhanced for loop.
- Using
ArrayList Algorithms: Searching, Filtering, and Replacing
Once you’re comfortable with ArrayList basics, you apply the same algorithmic thinking you used with arrays—but with a few extra considerations:
size()can change while your loop runs.- Insertions/removals shift indices.
- Elements are objects, so equality often requires
.equals().
Equality: == vs .equals() in collections
For primitives, == checks value equality. For objects, == checks whether two references are the exact same object.
In collections, you usually want logical equality, so you typically use .equals():
if (list.get(i).equals("AP")) { ... }
A common misconception is that == “works on strings.” Sometimes it appears to, due to string interning, but it is not reliable and is not what you should use for content comparison.
Linear search (finding an element)
The fundamental searching method in AP CSA contexts is linear search: look at each element until you find a match or reach the end.
Why it matters: it’s the default when the list is unsorted, and it’s easy to implement correctly.
public static int indexOfFirst(ArrayList<String> list, String target) {
for (int i = 0; i < list.size(); i++) {
if (list.get(i).equals(target)) {
return i;
}
}
return -1;
}
Key design choice: returning -1 when not found is a standard Java pattern (also used by many library methods).
Replacing based on a condition
Replacing means you keep the same size but update some elements.
Example: replace all negative numbers with 0.
public static void clampNegatives(ArrayList<Integer> nums) {
for (int i = 0; i < nums.size(); i++) {
if (nums.get(i) < 0) {
nums.set(i, 0);
}
}
}
Using set is important: you cannot assign directly like nums[i] = 0 because ArrayList is not an array.
Filtering (removing based on a condition)
Filtering changes the size, so you must handle shifting.
Example: remove all values greater than 100.
public static void removeTooLarge(ArrayList<Integer> nums) {
for (int i = nums.size() - 1; i >= 0; i--) {
if (nums.get(i) > 100) {
nums.remove(i);
}
}
}
Going backward avoids index-shift problems.
Combining algorithms: counting + conditional logic
Many FRQs ask you to compute something like “the number of times a pattern occurs” or “the longest run.” These are still traversals, but you keep extra state.
Example idea: count how many adjacent pairs are equal.
public static int countAdjacentMatches(ArrayList<String> list) {
int count = 0;
for (int i = 0; i < list.size() - 1; i++) {
if (list.get(i).equals(list.get(i + 1))) {
count++;
}
}
return count;
}
Notice the loop bound: i < list.size() - 1 so that i + 1 stays valid.
Strings and collections: .equals and compareTo
When sorting or ordering strings, Java uses compareTo (lexicographic order). You don’t usually need to implement compareTo, but you should understand that sorting strings alphabetically relies on this ordering.
Exam Focus
- Typical question patterns
- Implement or trace linear search and return a sentinel value when not found.
- Write code that removes items matching a condition without skipping elements.
- Determine whether
==vs.equals()is correct for collection elements.
- Common mistakes
- Using
==to compareStringvalues from a list. - Looping to
i < list.size()while accessingi + 1. - Removing elements in a forward loop and skipping shifted elements.
- Using
Sorting Collections with Library Methods (and What You Can Conclude From Sorting)
Sorting puts elements into a defined order (for example, ascending numbers or alphabetical strings). In AP CSA, you’re typically expected to recognize and use Java’s library sorting tools and reason about the results.
Sorting matters because it enables simpler solutions to many tasks:
- Finding minimum/maximum becomes trivial after sorting.
- You can detect duplicates by checking neighbors.
- You can compute medians (middle element(s)).
- Many data processing tasks become easier once data is ordered.
Sorting ArrayLists with Collections.sort
To sort an ArrayList of objects that have a natural ordering (like String or Integer), you can use:
import java.util.ArrayList;
import java.util.Collections;
ArrayList<String> words = new ArrayList<>();
words.add("banana");
words.add("apple");
words.add("cherry");
Collections.sort(words);
System.out.println(words); // [apple, banana, cherry]
Key points:
- The list is sorted in place (the same list object is rearranged).
- The element type must be comparable in a natural way (common wrapper types and
Stringare).
Sorting arrays with Arrays.sort
For arrays, Java provides Arrays.sort.
import java.util.Arrays;
int[] nums = {4, 1, 9, 2};
Arrays.sort(nums);
System.out.println(Arrays.toString(nums)); // [1, 2, 4, 9]
Arrays.toString is a convenient way to print arrays for debugging; you should recognize it if it appears.
What sorting changes (and what it doesn’t)
Sorting changes order, not membership:
- Same elements, rearranged.
- Size/length stays the same.
After sorting:
- Minimum is at index
0. - Maximum is at index
size - 1(orlength - 1). - Equal items become adjacent.
Worked example: using sorting to count distinct values
Suppose you have an ArrayList<Integer> and want to count how many distinct values appear.
Reasoning:
- If the list is sorted, duplicates are adjacent.
- You can count how many times the value changes as you traverse.
public static int countDistinct(ArrayList<Integer> nums) {
if (nums.size() == 0) return 0;
Collections.sort(nums);
int distinct = 1;
for (int i = 1; i < nums.size(); i++) {
if (!nums.get(i).equals(nums.get(i - 1))) {
distinct++;
}
}
return distinct;
}
Two important notes:
- This modifies the original list (because sorting is in place). On an exam, that side effect may matter.
- For
Integer, using.equalsis correct.
Being careful about side effects
A common exam theme is whether a method changes the list passed in. Sorting will rearrange the list object, so if other parts of the program rely on the original order, sorting is a significant side effect.
If you needed to preserve original order, you’d make a copy first—but copying itself is not always emphasized in AP CSA questions. Still, you should be aware that “sort” is not a harmless read-only operation.
Exam Focus
- Typical question patterns
- Predict list/array contents after calling a sort method.
- Use sorted order to reason about min/max, duplicates, or median positions.
- Determine whether sorting changes the original collection (side effects).
- Common mistakes
- Forgetting to import
CollectionsorArraysin code snippets. - Assuming sorting returns a new list rather than modifying the existing one.
- Using
==instead of.equals()when checking for adjacent duplicates after sorting.
- Forgetting to import
2D Arrays: Grids, Tables, and Nested Traversal
A 2D array in Java is an array whose elements are themselves arrays. It’s often used to model a grid or table, such as:
- a seating chart (rows and columns)
- a game board
- an image (pixels)
- daily temperatures over weeks (week × day)
Even if you think of it as “a rectangle,” Java represents it as “an array of rows.” That representation explains many 2D-array details that show up on AP questions.
Declaring and creating 2D arrays
Example: 3 rows, 4 columns:
int[][] grid = new int[3][4];
Default values apply just like 1D arrays (0 for int, null for references, etc.).
You can also initialize with nested braces:
int[][] grid = {
{1, 2, 3},
{4, 5, 6}
};
This has 2 rows and 3 columns.
length in 2D arrays
This is one of the most important ideas:
grid.lengthis the number of rows.grid[r].lengthis the number of columns in row r.
Students often try grid[0].length for columns (which works for rectangular arrays), but grid[r].length is the more general and correct way to think about it.
Ragged arrays (rows can have different lengths)
Because each row is an array, row lengths can differ:
int[][] ragged = {
{1, 2},
{3, 4, 5},
{6}
};
Here, ragged[1].length is 3, but ragged[2].length is 1.
This matters on the exam because you must use ragged[r].length in loops, not assume all rows have the same column count.
Traversing 2D arrays with nested loops
The standard traversal uses nested loops:
for (int r = 0; r < grid.length; r++) {
for (int c = 0; c < grid[r].length; c++) {
System.out.println(grid[r][c]);
}
}
This reads row by row (often called “row-major order”).
Common 2D array algorithms
1) Sum all values
public static int sumAll(int[][] grid) {
int sum = 0;
for (int r = 0; r < grid.length; r++) {
for (int c = 0; c < grid[r].length; c++) {
sum += grid[r][c];
}
}
return sum;
}
2) Count matches
Count how many times a value appears:
public static int countValue(int[][] grid, int target) {
int count = 0;
for (int r = 0; r < grid.length; r++) {
for (int c = 0; c < grid[r].length; c++) {
if (grid[r][c] == target) {
count++;
}
}
}
return count;
}
3) Work with neighbors (grid logic)
Grid problems often involve checking adjacent cells (up/down/left/right). The key is to prevent out-of-bounds access by verifying row/column indices are in range before checking a neighbor.
For example, to check the cell to the right of (r, c), you must ensure c + 1 < grid[r].length.
Enhanced for loops with 2D arrays
You can use enhanced for loops, but you need two levels:
for (int[] row : grid) {
for (int value : row) {
System.out.println(value);
}
}
This is convenient for read-only traversals and simple aggregations. If you need indices (for neighbor checks or writing back to a specific position), index-based loops are usually better.
What goes wrong in 2D arrays
- Confusing rows and columns (
grid.lengthvsgrid[0].length). - Using
grid[0].lengthfor all rows in a ragged array. - Off-by-one errors in neighbor checks.
Exam Focus
- Typical question patterns
- Trace nested loops and determine which elements are visited (and in what order).
- Write methods that compute totals/counts or modify a 2D array.
- Reason about bounds checks for neighbors in a grid.
- Common mistakes
- Using the wrong
length(rows vs columns). - Assuming rectangular shape when the array could be ragged.
- Accessing neighbors without checking boundaries first.
- Using the wrong
Choosing Between Arrays and ArrayLists (and Recognizing Them in FRQs)
A big part of mastering data collections is choosing the right tool—and then applying the correct traversal/modification strategy.
When an array is a better fit
Use an array when:
- The number of elements is fixed or known ahead of time.
- You want simple, fast indexed access with minimal overhead.
- You’re modeling something naturally fixed-size (days in a week, months in a year, a fixed set of exam scores).
A typical AP-style example is processing a fixed set of inputs stored in an array.
When an ArrayList is a better fit
Use an ArrayList when:
- The size changes during the program.
- You need to insert/remove items often.
- You want convenient methods like
addandremove.
A typical AP-style example is filtering a list of names based on a condition, removing items as you go.
Recognizing common FRQ patterns
AP CSA free-response questions frequently embed collection logic in a story context. The programming skills are the same:
- “Compute a statistic”: sum/count/max/min traversal.
- “Update all elements”: in-place transformation (arrays use
arr[i] = ...; lists useset). - “Remove items that match a rule”: shifting logic (ArrayList removal patterns are especially common).
- “Work with a grid”: nested loops and careful bounds.
Method design: parameters and side effects
Because arrays/ArrayLists are references, a method can modify the collection passed in.
Example: a method that doubles each element in an array will permanently change the caller’s array:
public static void doubleAll(int[] a) {
for (int i = 0; i < a.length; i++) {
a[i] *= 2;
}
}
This is not “good” or “bad” by itself—it’s a design choice. But on exam questions, you must correctly predict whether modifications persist.
A mental model that helps
Think of:
- an array as a row of fixed mailboxes (numbered 0 to length-1)
- an ArrayList as a row of mailboxes that can be inserted/removed, causing mailbox numbers to be reassigned after the change
This explains why removing shifts indices and why you must be careful in loops.
Exam Focus
- Typical question patterns
- Decide whether code is correct for an array vs an ArrayList (
lengthvssize,[]vsget/set). - Predict whether a method modifies the original collection.
- Debug index-shift issues after insertions/removals.
- Decide whether code is correct for an array vs an ArrayList (
- Common mistakes
- Writing
list[i]orarr.get(i)(mixing syntax). - Forgetting that removing from an ArrayList shifts indices and changes
size(). - Assuming a method that receives a collection parameter works on a copy instead of the original.
- Writing