CompSci.rocks
FRQcsapa

Attendance: 2026 FRQ 3

A step-by-step solution to the 2026 AP CSA FRQ 3 (Attendance), covering matching records across two ArrayLists by a shared ID field in Java.

Comparing attendance records for the same students across two different classes is the task in this AP Computer Science A free-response question — and unlike most FRQs, this one asks for a single method rather than splitting the work into two parts.

What This FRQ Tests

  • AP CSA units: Unit 6 (Array) and Unit 7 (ArrayList)
  • Core skill: matching elements across two separate ArrayLists by comparing a shared identifying field, rather than by matching index position
  • Secondary skill: nesting one loop inside another to compare every element of one list against every element of another
  • Official category: "Array/ArrayList" — this year's version asks for a single method rather than the usual two-part structure, but it's still always FRQ 3 on the AP CSA exam

The Setup

  • The given CourseRecord class (not modified) provides:
    • String getStudentID() — a unique ID for the student
    • int getAbsences() — how many times that student has been absent in this course
  • Attendance holds two fields:
    • private ArrayList<CourseRecord> historyList
    • private ArrayList<CourseRecord> mathList
  • You're asked to write one method:
    • int moreHistoryThanMathAbsences() — counts students who appear in both lists, but only those with strictly more absences in the history list than the math list

Writing moreHistoryThanMathAbsences()

The Rule, Broken Down

  1. A student only counts if their ID appears in both historyList and mathList.
  2. Of those students, only count the ones whose history-course absences are strictly greater than their math-course absences.
  3. Every student ID is guaranteed to appear at most once in each list, so there's no risk of double-matching within a single list.

Step-by-Step Approach

  1. Start a counter at 0.
  2. Loop through every record in historyList.
  3. For each one, search through every record in mathList looking for a matching student ID.
  4. If a match is found, compare the two records' absence counts — if the history record's count is higher, increment the counter.
  5. After both loops finish, return the counter.

The Code

public int moreHistoryThanMathAbsences()
{
    int count = 0;

    for (int i = 0; i < historyList.size(); i++)
    {
        CourseRecord historyRecord = historyList.get(i);

        for (int j = 0; j < mathList.size(); j++)
        {
            CourseRecord mathRecord = mathList.get(j);

            if (historyRecord.getStudentID().equals(mathRecord.getStudentID()))
            {
                if (historyRecord.getAbsences() > mathRecord.getAbsences())
                {
                    count++;
                }
            }
        }
    }

    return count;
}

Why Each Piece Matters

  • A nested loop, not two separate loops — since a student's position in historyList has no relationship to their position in mathList, the only way to find "the same student in both lists" is to check every combination of one record from each.
  • .equals() to compare student IDs, never ==getStudentID() returns a String, and two separately-built String objects holding identical characters aren't guaranteed to be the same object in memory.
  • The absences comparison is nested inside the ID-match check — a student's absence counts are only meaningful to compare once you already know you're looking at the same student in both lists.
  • >, not >= — the rule is specifically "more absences in history," so a tie doesn't count.

Tracing the Example

Using the question's own data — historyList has IDs rc29(1), br98(1), dr03(2), ot32(2), sq98(3), ry00(1), and mathList has fr27(2), sq98(1), dr03(2), dk12(1), ot32(1), js33(0), ry00(3) (absences shown in parentheses):

Student ID In both lists? History absences Math absences History > Math?
dr03 yes 2 2 no
ot32 yes 2 1 yes
sq98 yes 3 1 yes
ry00 yes 1 3 no

Every other ID in either list has no match in the other, so those never even reach the absences comparison. Final count: 2 — matches the question exactly.

Common Mistakes to Avoid

  • Assuming matching positions correspond to the same student (e.g. comparing historyList.get(i) to mathList.get(i)). The two lists aren't guaranteed to list the same students in the same order, or even contain the exact same set of students at all.
  • Comparing student IDs with == instead of .equals(). This is one of the most common AP CSA point losses anywhere String comparison shows up.
  • Using >= instead of >. A student with equal absences in both courses doesn't have "more" absences in either one.
  • Forgetting that a student might appear in only one of the two lists. The nested-loop structure already handles this correctly (a record with no match anywhere in the other list just never triggers the count), but it's worth double-checking that no separate "assume every ID matches" shortcut sneaks in.

Key Takeaways

  • Matching records across two separate collections by a shared field — not by index — always means comparing every element of one against every element of the other with a nested loop.
  • String fields (like an ID) always compare with .equals(), never ==, no matter how deeply the comparison is nested inside other loops or conditions.
  • Not every AP CSA FRQ splits into two labeled parts — some ask for a single, more involved method instead. The same step-by-step approach (rule, plan, code, trace) still applies either way.

Related FRQs