Working with objects that remember.
When each object in a list carries state that persists across operations, your code must read it before deciding what to do — and update it after.
An ArrayList of stateful objects isn't just a container of values — it's a collection where each object has its own history. A BankAccount remembers its balance; a Player remembers their score; a Counter remembers how many times it's been incremented.
The pattern is to read state, decide, then update state for each object — often based on the object's own current value plus some external input.
On the AP exam, this appears whenever an FRQ involves a list of objects that change over multiple method calls — running totals, leveling up, processing transactions.
Read, decide, update — for each object.
The object's current state determines what happens next.
The template
for (StatefulType obj : list) {
// 1. read state via accessor
Type current = obj.getState();
// 2. decide based on current state (and possibly external input)
if (someCondition(current)) {
// 3. update via mutator
obj.updateState(...);
}
}
Concrete example: monthly interest
Assume a BankAccount class with getBalance() and deposit(double amount). Apply 1% interest to every account that has a positive balance:
public void applyInterest(ArrayList<BankAccount> accounts) {
for (BankAccount a : accounts) {
double balance = a.getBalance();
if (balance > 0) {
a.deposit(balance * 0.01);
}
}
}
The decision (whether to apply interest) and the amount (1% of the current balance) both depend on the object's existing state. Read first; then update.
State persists between method calls
Because the objects live in the same list across calls, their state accumulates. Calling applyInterest twice doubles the effect — the second pass operates on already-updated balances.
Order can matter
If one update affects later reads (rare in basic FRQs, common in simulation), you may need to compute all new values first, then apply them — a two-pass approach.
State-aware vocabulary.
These terms appear in any stateful-object FRQ.
- Stateful object — one whose fields persist and matter across method calls.
- Current state — the values of the object's instance variables at this moment.
- State-dependent update — a change whose magnitude depends on the existing state.
- Accumulating state — state that grows across repeated operations.
- Two-pass update — read all values first, then apply changes to avoid order-dependence.
- Side-effect call — a method invocation that exists for the state change, not the return value.
How stateful lists are tested.
Tracing across multiple method calls is the dominant pattern.
MCQ patterns to expect:
- "After three calls to methodX, what is the state of each object?" Trace each call in order, updating fields as you go.
- "Which accounts qualify for the operation?" Read the condition; apply per-object.
- "What if the mutator is called twice on the same object?" The state from the first call becomes input to the second.
FRQ tip: always read state via the accessor into a local variable before using it twice. This makes your reasoning explicit and prevents subtle re-evaluation bugs.
Process scores and level up players.
A state-dependent decision drives the update.
Setup. A Player class has accessors getScore() and getLevel() and mutators addScore(int pts) and levelUp(). Process a round: every player earns 50 points; any player whose score then reaches 100 or more levels up and resets to 0.
public void processRound(ArrayList<Player> players) {
for (Player p : players) {
p.addScore(50);
if (p.getScore() >= 100) {
p.levelUp();
p.addScore(-p.getScore()); // reset to 0
}
}
}
Trace. Start with three players at scores 30, 70, 90 and levels 1, 1, 2.
- Player 1: 30 + 50 = 80. Below 100. Level stays at 1.
- Player 2: 70 + 50 = 120. ≥ 100. Levels up to 2; score resets to 0.
- Player 3: 90 + 50 = 140. ≥ 100. Levels up to 3; score resets to 0.
Final state: scores 80, 0, 0; levels 1, 2, 3.
Why this matters. Each decision depended on the post-add score — so the order of operations matters. Read state after every mutation if subsequent logic depends on it.
Errors in stateful traversal.
Most come from reading state at the wrong moment.
- Reading state before the mutation when the decision depends on the new value. Read after, or recompute.
- Reading state after the mutation when the decision depended on the old value. Save the old value first.
- Calling a mutator that returns nothing and trying to use the "return value". Mutators are usually
void. - Not handling the accumulator carefully. Calling
processRoundtwice should produce twice the effect — make sure your code respects that. - Forgetting that two references can share an object. Updating through one reference changes the object everywhere.
Stateful traversal at a glance.
The three steps and where things can go wrong.
Stateful Object Reference
AP Quick Reference| Step | Action | AP Exam Tip |
|---|---|---|
| 1 | Read state via accessor | Store in a local variable if used twice. |
| 2 | Decide based on state | Use a boolean expression on the read value. |
| 3 | Update via mutator | Call the exact method named in the spec. |
| Order matters | Read vs update sequence | Decide whether you need pre- or post-state. |
| Repeated calls | State accumulates | Each call sees the prior call's effects. |
How to master stateful lists.
Trace each object through multiple calls until accumulation is intuitive.
Use the three practice tools below this lesson in order:
- MCQ Practice — for each problem, write a small table with one row per object and one column per method call. Update cells as you trace.
- Java Lab — build a
BankAccountorPlayerclass, then write methods that read state, decide, and update. Run them twice and confirm state accumulates correctly. - FRQ Practice — when the rubric mentions "current balance" or "current score", read state into a local variable first. Then your update math is unambiguous.
If you can trace three objects through three method calls without confusion, stateful-list FRQs become routine.
Practice — attempt these now.
AP-style assessments aligned to this lesson. Time them.