Unit 1.15: String Manipulation
You have already been using String objects since the very first unit to display text and store simple data. In this section, we will look deeper into how strings work behind the scenes and explore the powerful methods provided by the Java API for detailed string manipulation.
Creating Strings
As a reminder, a String represents a sequence of characters.
- Strings are objects, but they are so fundamental that Java provides a shorthand (literals) to create them. Using
new String()is valid but less efficient because it bypasses the "string pool."
It can be created from a string literal or by using the new keyword. When you use new String() a brand new String object is created instead of using the one already available in the String pool and so is considered less efficient.
Task: Defining Strings using literals and the new keyword.
// Using a string literal (most common)
String greeting = "Hello, World!";
// Using the 'new' keyword
String farewell = new String("Goodbye!");
String Package
The String class is part of the java.lang package and is available by default in all Java programs.
String Immutability
String objects are immutable; their contents cannot be changed after creation.
- Once a
Stringobject is created, it cannot be modified. Methods liketoUpperCase()or concatenation do NOT change the original string; they create and return a brand-newStringobject.
When you perform an operation that seems to modify a string, Java creates a new String object with the new value.
Task: Observing the effects of string immutability.
String s = "hello";
s.toUpperCase(); // This creates a new "HELLO" string, but doesn't change s
System.out.println(s); // Prints "hello"
s = s.toUpperCase(); // Now s refers to the new "HELLO" object
System.out.println(s); // Prints "HELLO"
String Concatenation
The + or += operators are used to concatenate (join) strings.
- In Java, the
+operator is "overloaded." If any operand is aString, the operator performs concatenation instead of addition.
The Rules of Concatenation
- Immutability: Concatenation creates a new
Stringobject. It does not modify the original strings. - Left-to-Right Evaluation: Java evaluates expressions from left to right. This is critical when mixing numbers and strings.
- If both operands are numbers,
+performs addition. - If at least one operand is a
String,+performs concatenation.
- If both operands are numbers,
Tricky Examples
Task: Applying evaluation rules to string concatenation.
// Case 1: Numbers first
// 1 + 2 is calculated as 3 (int). Then "3" is concatenated.
System.out.println(1 + 2 + "3"); // Prints "33"
// Case 2: String first
// "1" + 2 becomes "12" (String). Then "12" + 3 becomes "123".
System.out.println("1" + 2 + 3); // Prints "123"
// Case 3: Mixed
// 1 + 2 = 3. Then 3 + "3" = "33". Then "33" + 4 = "334".
System.out.println(1 + 2 + "3" + 4 + 5); // Prints "3345"
Task: Joining strings using variables.
String firstName = "John";
String lastName = "Doe";
String fullName = firstName + " " + lastName; // Creates "John Doe"
Concatenation and Printing Objects
When you concatenate a String with an object, or pass an object directly to System.out.println(), Java automatically calls the object's toString() method.
- The
toString()method provides a way to represent an object as text. By overriding it, classes can define exactly what information is shown when an instance is printed.
Implicit toString() Call
- Concatenation:
"Value: " + myObjbecomes"Value: " + myObj.toString() - Printing:
System.out.println(myObj)becomesSystem.out.println(myObj.toString())
Default vs. Overridden Behavior
Every class in Java automatically inherits the toString() method from the Object class (the top-level parent class of all objects).
- Default Behavior: If a class does not define its own
toString()method, it uses the inherited version. This default implementation returns a string consisting of the class name followed by an '@' sign and the hash code (e.g.,Student@1a2b3c). - Overridden Behavior: Most classes (like
Integer,Double, and custom classes) overridetoString()to return meaningful data (e.g.,"5"or"Alice, Grade: 10").
Task: Overriding the toString() method in a custom class.
public class Student {
String name;
public Student(String n) { name = n; }
// Overriding toString to print useful info instead of hash code
public String toString() {
return "Student: " + name;
}
}
Student s = new Student("Alex");
System.out.println(s); // Prints "Student: Alex" instead of Student@...
Printing this
Inside a method, the keyword this refers to the current object. Calling System.out.println(this) will print the string representation of the current object instance.
String Indexing
A String uses zero-based indexing, with indices ranging from 0 to length() - 1. Attempting to access an index outside of this range will result in an IndexOutOfBoundsException.
Common String Methods
The String class provides several essential methods for analyzing and manipulating text. These methods are part of the Java Quick Reference for the exam:
| Method Signature | Description | Result Example (s = "Java") |
|---|---|---|
int length() |
Returns the number of characters in the string. | s.length() → 4 |
String substring(int from, int to) |
Returns a substring from from to to - 1. |
s.substring(0, 2) → "Ja" |
String substring(int from) |
Returns a substring from from to the end. |
s.substring(2) → "va" |
int indexOf(String str) |
Returns the index of the first occurrence of str. |
s.indexOf("v") → 2 |
boolean equals(String other) |
Returns true if the content is identical. |
s.equals("java") → false |
int compareTo(String other) |
Compares strings alphabetically. | s.compareTo("Apple") → Positive |
Visualizing String Methods
How compareTo Works
The compareTo method compares two strings character by character based on their Unicode (ASCII) values.
Why is "Java".compareTo("Apple") positive?
- Java looks at the first characters:
JvsA. - In the alphabet,
Jcomes afterA. - Since
Jis "greater than"A, the method returns a positive integer.
General Rules:
- Result < 0: The first string comes before the other string alphabetically (e.g.,
"Apple".compareTo("Banana")). - Result == 0: The two strings are identical (e.g.,
"Java".compareTo("Java")). - Result > 0: The first string comes after the other string alphabetically (e.g.,
"Zebra".compareTo("Ant")).
Note: Uppercase letters come before lowercase letters in the ASCII table (e.g., 'Z' comes before 'a').
Substring Rules & Edge Cases
A common point of confusion is using the string length as an index.
- End Index (Exclusive): In
substring(start, end), theendindex can be equal to the string length. Since the character at theendindex is excluded, this simply means "go up to the very end".- Example:
"Java".substring(0, 4)returns"Java"(Length is 4).
- Example:
- Start Index (Empty String): In
substring(start), thestartindex can be equal to the length. This returns an empty string"".- Example:
"Java".substring(4)returns"".
- Example:
- Out of Bounds: Any index greater than the length, or negative, will cause an error.
- Example:
"Java".substring(5)-> Error.
- Example:
Task: Using standard String library methods.
String text = "Java Programming";
System.out.println("Length: " + text.length()); // 16
System.out.println("Substring: " + text.substring(5, 12)); // "Program"
System.out.println("Index of 'a': " + text.indexOf("a")); // 1
System.out.println("Equals 'java programming'?: " + text.equals("java programming")); // false
Getting a Single Character
A single-character substring at a specific index can be created using substring(index, index + 1).
Task: Extracting a single character as a String.
String word = "example";
String firstLetter = word.substring(0, 1); // "e"