01
Overview

Removing strings that contain a target substring.

Combine substring detection with safe removal to clean lists of Strings or text fields.

A common AP-style task: given an ArrayList<String> (or a list of objects with text fields), delete every entry whose String contains a given substring. The pattern blends two earlier skills: indexOf-based detection and backward-iteration removal.

Substring matching tests for a sequence of characters anywhere in the target — not for an exact match. "unhappy".indexOf("happy") returns 2, indicating the substring appears starting at index 2.

On the AP exam, this pattern appears in text-cleaning FRQs: filter chat messages, remove banned words, delete entries with a flagged tag.

02
Core Concept

indexOf for detection; backward loop for removal.

Two patterns combined into one method.

Detecting a substring

if (text.indexOf(target) != -1) {
    // substring is present somewhere
}

indexOf returns the position of the first occurrence, or -1 when the substring is absent. The != -1 check is the standard "contains" test in AP CSA scope.

The full template

public void removeContaining(ArrayList<String> list, String target) {
    for (int i = list.size() - 1; i >= 0; i--) {
        if (list.get(i).indexOf(target) != -1) {
            list.remove(i);
        }
    }
}

Backward iteration is essential because each removal shifts later elements left.

For object fields

If the list holds objects with a text accessor, swap list.get(i) for list.get(i).getName() (or whichever accessor returns the text):

for (int i = list.size() - 1; i >= 0; i--) {
    if (list.get(i).getName().indexOf(target) != -1) {
        list.remove(i);
    }
}

Case sensitivity

indexOf is case-sensitive: "Hello".indexOf("hello") returns -1. AP problems usually want exact-case matching. If the prompt asks for case-insensitive, normalize both Strings to lowercase first.

Empty target string

"".indexOf("any string") returns 0 — the empty string is considered present at the start of every String. Most AP problems don't ask about this case, but watch for it if the prompt allows empty targets.

03
Key Vocabulary

Vocabulary for text filtering.

Used in any "remove containing" or "filter by text" problem.

Vocabulary
  • Substring — a contiguous sequence of characters within a String.
  • Contains — a String includes the target substring anywhere.
  • indexOf — returns the position of the substring, or -1.
  • Case sensitivity — whether 'A' and 'a' are treated as the same character.
  • Normalize — converting strings to a uniform form (e.g., lowercase) before comparison.
  • Backward removal — the safe pattern for deleting during a loop.
04
AP Exam Focus

How substring removal is tested.

Contains-vs-equals confusion and missing backward iteration dominate.

Exam Focus

What FRQ graders check:

  • Contains, not equals. The prompt says "contains" — use indexOf, not .equals().
  • Backward iteration. Removal during a forward loop skips entries.
  • Correct sentinel. indexOf returns -1 when absent.
  • Right field. For object lists, call the accessor named in the prompt.

MCQ patterns: tracing the list after a removal pass; identifying which entries match the contains condition.

05
Worked Example

Remove every banned message.

Trace the backward loop and the contains check.

Worked Example AP-style reasoning

Problem. Remove every message that contains the word "spam".

public void filterSpam(ArrayList<String> messages) {
    for (int i = messages.size() - 1; i >= 0; i--) {
        if (messages.get(i).indexOf("spam") != -1) {
            messages.remove(i);
        }
    }
}

Input. ["hello there", "buy spam now", "spam offer", "good morning", "no spammers here"].

Trace backward.

  • i=4: "no spammers here". indexOf("spam") = 3 (matches inside "spammers"). Remove. List: ["hello there", "buy spam now", "spam offer", "good morning"].
  • i=3: "good morning". indexOf("spam") = -1. Keep.
  • i=2: "spam offer". indexOf("spam") = 0. Remove. List: ["hello there", "buy spam now", "good morning"].
  • i=1: "buy spam now". indexOf("spam") = 4. Remove. List: ["hello there", "good morning"].
  • i=0: "hello there". indexOf("spam") = -1. Keep.

Final. ["hello there", "good morning"].

Why this matters. "no spammers here" was caught even though "spam" wasn't the whole word — that's the contains behavior. If the prompt wanted exact-word matching, you'd use .equals() or extra logic; "contains" is broader.

06
Common Mistakes

Substring-removal pitfalls.

Most come from picking the wrong matching test or loop direction.

Watch Out
  • Using .equals() when the prompt says "contains". Misses entries where the substring is part of a larger word.
  • Forward loop with remove(i). Skips entries — the classic safe-removal bug.
  • Comparing indexOf result with == 0. That only matches when the substring is at the very start. Use != -1.
  • Case-sensitivity mismatch. Searching for "SPAM" won't match "spam" without normalization.
  • Using == on Strings. Always use indexOf or .equals().
  • Wrong field on objects. Call getName() when that's the relevant text accessor; don't call toString() unless specified.
07
Reference Table

Substring removal at a glance.

The right test plus the right loop.

Substring Removal Reference

AP Quick Reference
Prompt phrase Test AP Exam Tip
"contains the substring" indexOf(target) != -1 Matches anywhere in the String.
"equals the value" .equals(target) Exact match only.
"starts with" indexOf(target) == 0 Match at the front.
Loop direction Backward Safe for removal.
Case-insensitive Lowercase both before comparing Only when the prompt requires.
08
Practice Tip

How to lock in substring removal.

Pick the right test for the prompt; pair it with the backward loop.

Practice Strategy

Use the three practice tools below this lesson in order:

  • MCQ Practice — for each option, read the prompt's verb: "contains" → indexOf; "equals" → .equals(). Then verify backward iteration.
  • Java Lab — write methods that remove entries containing "@", "spam", or any other substring. Test with edge cases like empty Strings and exact-word matches.
  • FRQ Practice — chain the contains test with the backward removal loop. If the list holds objects, call the right accessor on each one.

If you can match "contains" → indexOf → backward loop instantly, this entire problem class is solved.

09
Section · 09

Practice — attempt these now.

AP-style assessments aligned to this lesson. Time them.

Topic Quiz 40 min 40 marks Pending

AP CSA Topic Practice: Substring-Based Removal

AP-style topic practice assessment

Start
FRQ Practice 30 min 18 marks Pending

AP CSA Unit 06 Topic 14 Substring-Based Removal FRQ Practice

AP-style topic practice assessment

Start