1.15 String Manipulation
Create strings, concatenate them, and use methods like length(), substring(), indexOf(), and equals().
1. Reference Guide
Key Topics
| Term | Definition | Example |
|---|---|---|
| Utility class | A class that is never instantiated; you call its static methods directly on the class name. | Math.abs(-5); |
| String literal | Creating a String object with quotation marks. |
String s = "hello"; |
| Immutable | A String object’s characters can never be changed after creation. |
s.concat("!") returns a new String; s itself is unchanged |
| Wrapper class | A reference-type class that holds a primitive value as an object. | Integer, Double |
| Autoboxing | The compiler automatically converting a primitive into its wrapper class. | Integer i = 5; |
| Unboxing | The compiler automatically converting a wrapper object back to a primitive. | int x = i; |
- Strings are immutable: every method that looks like it changes a
Stringactually returns a brand-new one - Wrapper classes let primitives be used where an object is required
Common Java Utility Classes
| Class | Package | Use |
|---|---|---|
Arrays |
java.util |
Static helpers for arrays, e.g. Arrays.sort(), Arrays.toString() |
Math |
java.lang |
Static helpers for numeric operations |
HashMap |
java.util |
Key-value storage (not a utility class itself, but commonly paired with one) |
String Methods
| Syntax | Definition |
|---|---|
String(String str) |
Constructs a new String object with the same characters as str |
int length() |
Returns the number of characters in the String |
String substring(int from, int to) |
Returns the substring beginning at from, up to (not including) to |
String substring(int from) |
Returns the substring beginning at from to the end |
int indexOf(String str) |
Returns the first occurrence of str, or -1 if not found |
boolean equals(String other) |
Returns true if the two Strings hold the same characters |
int compareTo(String other) |
Returns <0 if this is less than other, 0 if equal, >0 if greater |
Wrapper Classes
| Syntax | Definition |
|---|---|
Integer.valueOf(int value) |
Returns an Integer object representing value (autoboxing does this for you) |
Integer.MIN_VALUE / Integer.MAX_VALUE |
The smallest/largest value an int or Integer can hold |
int intValue() |
Returns an Integer’s value as a primitive int |
Double.valueOf(double value) |
Returns a Double object representing value |
double doubleValue() |
Returns a Double’s value as a primitive double |
Math Class Quick Reference
| Syntax | Definition |
|---|---|
static int abs(int x) |
Absolute value of an int |
static double abs(double x) |
Absolute value of a double |
static double pow(double base, double exponent) |
base raised to exponent |
static double random() |
A random double between 0.0 and 1.0 |
Spotting Immutability
- A method call looks like it should “change” a
String(concat,substring,toUpperCase) → it always returns a newString; print the original again to confirm it didn’t change - You need a primitive where an object is required (like a generic collection) → use the matching wrapper class, and let autoboxing/unboxing convert automatically
- You want static helpers with no object of your own → check
java.lang.Mathorjava.util.Arraysbefore writing your own
2. LxD Cycle Process
Empathize: I noticed students write s1.concat(s2) or s1.substring(1) and expect s1 itself to have changed. They treat String methods like they treat ArrayList methods (add, remove), which really do mutate the object — but every String method that looks like it “changes” the string actually returns a brand-new String object.
Define:
- POV: CSA students need to internalize that
Stringobjects are immutable because the AP Exam frequently tests code where a student wrongly assumes a String method changed the original variable. - Learning Goal: Students will create
Stringobjects using literals and theStringconstructor, correctly predict the result of concatenation and commonStringmethods, and use wrapper classes (Integer,Double) to move between primitives and objects.
Ideate:
- HMW Question: How might we make immutability visible instead of invisible — something students can see fail, not just be told about?
- Activity: Run a chain of
Stringmethod calls, print the original variable after each one, and confirm it never changed — only the return value did.
Prototype & Test: In a trial run, one Popcorn Hack cell was an exact, unmodified copy of the worked example instead of a real task, so students had nothing to actually practice. I rewrote it as a TODO stub with a concrete, checkable requirement.
3. College Board Requirements
AP CSA Unit 1, Topic 1.15 String Manipulation. Quoted from the course and exam description (College Board, 2025, pp. 48-49):
- “A String object represents a sequence of characters and can be created by using a string literal or by calling the String class constructor.”
- “A String object is immutable, meaning once a String object is created, its attributes cannot be changed. Methods called on a String object do not change the content of the String object.”
The immutability rule the College Board describes is formally specified in the Java Language Specification (Gosling et al., 2023, §4.3.3); see References.
4. Lesson Plan
Learning Objective: By the end of this lesson, you will be able to create String objects and predict the result of combining them, use common String methods correctly, and use the Integer/Double wrapper classes to convert between primitives and objects.
Success Criteria: You can trace through a sequence of String method calls and correctly state the value of every variable afterward, including confirming that the original String never changed.
Tech Talk & Introduction (5 minutes)
In Java, objects are instances of classes that bundle state (attributes) and behavior (methods). A utility class — like Math, Arrays, or Collections — is never instantiated; it just provides static methods you call directly on the class name.
String is the utility-adjacent object type you will use the most. A String object can be created with a literal ("hello") or with the new String(...) constructor, and it is immutable: no method ever changes the characters inside an existing String object. Concatenation with + doesn’t modify either operand — it produces a brand-new String.
Why do we do this? Because String is immutable, two variables can safely share the same String object with no risk that one will unexpectedly change the other — a guarantee mutable objects like arrays or ArrayList do not give you.
5. Code Examples
A. Simple: A Utility Class in Action
import java.util.Arrays;
public class ArraySortExample {
public static void main(String[] args) {
int[] numbers = {5, 2, 9, 1, 5, 6};
Arrays.sort(numbers);
System.out.println(Arrays.toString(numbers));
}
}
ArraySortExample.main(null);
B. Simple: Declaring and Initializing an Object
new Dog() allocates memory for a Dog object and invokes its constructor.
public class Dog {
public String Name;
public int Age;
public void Bark(int times) {
for (int i = 0; i < times; i++) {
System.out.println("Bark");
}
}
public static void main(String[] args) {
Dog dog = new Dog();
dog.Bark(5);
}
}
Dog.main(null);
C. Intermediate: Calling a Non-Void Method
public class Dog {
public String Name; //instance variables
public int Age;
public Dog(String name, int age) { //construction method
Name = name;
Age = age;
}
public String getName() { //non-void method that returns a String
return Name;
}
public static void main(String[] args) { //main code
Dog d = new Dog("Larry", 4);
System.out.println(d.getName());
}
}
Dog.main(null);
D. Intermediate: String Immutability and Concatenation
s3 = s1 + s2 creates a new String. Watch how s1 is printed again afterward, unchanged, to confirm it.
public class Strings_demo {
public static void main(String[] args) { //main code
String s1 = "hello"; // The way you are probably used to for string objects
String s2 = new String("hello"); // an alternate method to create the same string variable
System.out.println(s1);// these two println statements should print the same thing
System.out.println(s2);
String s3 = s1+s2; // s3 is a concatenation of s1 and s2
System.out.println(s3);
System.out.println(s1); // the method doesn't actually change the String itself
String s4 = new String("In order to type out a \\\\ string in Java String, you need 4 \\'s \n You need 3 \\'s and 1 \" to type out a \\\""); // a demonstration of the escape sequences
System.out.println(s4);
}
}
Strings_demo.main(null);
E. Complex: Common String Methods
public class Strings_demo_2 {
public static void main(String[] args) { //main code
String s1 = "hello"; // Strings for demonstration
String s2 = new String("hihihellothere"); // Construction using the method
System.out.println(s2.length());
String s3 = s2.substring(4,9); // creating a substring of s1 from index 4 to 9-1
System.out.println(s3);
System.out.println(s1); // these should be the same
System.out.println(s2.indexOf(s1)); //returns the first occurence of hello in hihihellothere (4)
System.out.println(s2.equals(s1)); // returns if hello is the same as hihihellothere (it's not)
System.out.println(s2.compareTo(s1)); // compares hihihellothere to hello, since it greater since h=h and i>e, this returns a positive number
System.out.println(s1.compareTo(s2)); // the reversal of the above, returns a negative number
System.out.println(s3.equals(s1)); // returns if hello is the same as hello (it's)
System.out.println(s3.compareTo(s1)); // compares hello to hello, since they are the same, this returns a 0
System.out.println(s1);// none of these methods affect the original strings, since Strings are immutatble
System.out.println(s2);
System.out.println(s3);
}
}
Strings_demo_2.main(null);
F. Complex: Wrapper Classes, Autoboxing, and Unboxing
public class Unboxing_stream {
public static void main(String[] args) { //main code
int i1 = 10; // primitive data types
double d1 = 25.5;
Integer I1 = Integer.valueOf(i1); // Construction of the Wrapper classes version
Double D1 = Double.valueOf(d1);
System.out.println(i1); // The values correspond to their original values
System.out.println(I1);
System.out.println(d1);
System.out.println(D1);
int i2 = I1.intValue()+5; //usage of the intValue function
System.out.println(i2);
double d2 = D1.doubleValue()-1.3; //usage of the doubleValue function
System.out.println(d2);
System.out.println(Integer.MIN_VALUE); // the actual values of the MIN_VALUE and MAX_VALUE
System.out.println(Integer.MAX_VALUE);
Integer I2 = i1; // autoboxing bypasses the need for constructor methods
Double D2 = d1;
System.out.println(I2);
System.out.println(D2);
int i3 = I2+10; // unboxing without using any methods
double d3 = D2-1.3;
System.out.println(i3);
System.out.println(d3);
}
}
Unboxing_stream.main(null);
G. Bonus: The Math Utility Class
import static java.lang.Math.*; // implicit importation
public class maths_demo {
public static void main(String[] args) { //main code
double a=12.5; // ints we will use
int b=-5;
int c=4;
System.out.println(abs(a)); // prints the absolute values of a and b
System.out.println(abs(b)); // should have no effect on a but b should be turned to its opposite (the positive number)
System.out.println(pow(b,c)); // prints the result of b to c
System.out.println(random()*10>4); // returns true if a random number from 0 to 10 is greater than 4, this should return different values with different runs.
}
}
maths_demo.main(null);
6. Hacks & Practice Tasks
Submission Safety Rules (Read First)
[!IMPORTANT] To avoid grading errors, follow these rules exactly:
- Run every code cell and leave the output visible before submitting.
- Never claim a
Stringmethod changed the original variable — print the original again to prove whether it did or didn’t.- Use the wrapper-class methods from the Reference Guide (
valueOf, autoboxing) instead of the deprecatednew Integer(...)/new Double(...)constructors.
Popcorn Hack #1: Extend the Dog Class
[!TIP] Add the field or second object first, then the method, then test it by printing the result.
Modify the Dog class from Code Example C to demonstrate one of the following:
- An additional non-void method, or
- Multiple uses of the same non-void method on different objects
public class Dog {
public String Name;
public int Age;
public Dog(String name, int age) {
Name = name;
Age = age;
}
public String getName() {
return Name;
}
// TODO: add a second non-void method (for example getAge()),
// OR create a second Dog object and call getName() on both.
public static void main(String[] args) {
Dog d = new Dog("Larry", 4);
System.out.println(d.getName());
// TODO: call your new method here, or create + use a second Dog object
}
}
Dog.main(null);
Popcorn Hack #2: Find a Substring’s Position
Using the String methods from the Reference Guide, write a method that returns the position of a substring inside a string, and use System.out.println to prove it works.
public class SubstringFinder {
// TODO: write a method that takes a full string and a target substring,
// and returns the index where the substring starts (use indexOf).
public static void main(String[] args) {
// TODO: call your method and print the result to prove it works
}
}
// SubstringFinder.main(null);
Popcorn Hack #3: Math-Powered Number Guessing Game
Create a variation of the number guessing game using at least one method from the Math Class Quick Reference (random(), abs(), or pow()). Bonus points for creativity.
public class NumberGuessingGame {
// TODO: use Math.random() to generate a target number,
// then compare it to a guess (use Math.abs() to measure how close the guess was).
public static void main(String[] args) {
// TODO: run your game and print the result
}
}
// NumberGuessingGame.main(null);
Homework Hack
Once you have completed all three Popcorn Hacks above, submit the required quiz:
Grading Plan (1 Point Total)
Classroom Rubric
-
0.3 points: Popcorn completion All three Popcorn Hacks are completed, run, and produce correct output.
-
0.7 points: Homework completion Quiz submitted, demonstrating correct predictions for
Stringimmutability, concatenation, and wrapper-class autoboxing/unboxing questions.
Quick Validation Checklist
- Present: all code cells executed with visible output
- Present: at least one method call proving the original
Stringwas not changed - Absent: the deprecated
new Integer(...)/new Double(...)constructors - Present: quiz submission link followed
7. Lesson Revisions
Revision Made: I replaced both deprecated constructors with Integer.valueOf(...)/Double.valueOf(...), fixed the mismatched doubleValue() call, and rewrote the first Popcorn Hack as a real TODO stub with a concrete, checkable requirement. I also removed the original Dog.main(words) call in the first object-creation example, which silently depended on a words array defined in an unrelated earlier cell about Arrays.sort, so each Code Example now runs correctly on its own.
8. Feedback Evidence
Feedback Received: Peer review found that the Wrapper Classes code example used new Integer(i1) and new Double(d1), both of which are deprecated since Java 9 and were removed entirely in later JDK releases — meaning that cell would fail to compile on the notebook’s own Java 21 kernel. It also called D1.intValue() where the comment said “usage of the doubleValue function,” and the first Popcorn Hack was an exact copy of the worked example instead of an actual task.
9. References
College Board. (2025). AP Computer Science A: Course and exam description. https://apcentral.collegeboard.org/media/pdf/ap-computer-science-a-course-and-exam-description.pdf
Gosling, J., Joy, B., Steele, G., Bracha, G., & Buckley, A. (2023). The Java language specification: Java SE 21 edition (§4.3.3, The Class String). Oracle America. https://docs.oracle.com/javase/specs/jls/se21/html/jls-4.html
Submit Assignment
Need to update a submission later? Open the submissions dashboard.