String API & Operations
Character inspection, searching, substrings, transformations, tokenization traps, and alphabet frequency indexing
In Java, String instances are immutable UTF-16/Latin-1 character sequences. Because strings are immutable, any method that appears to modify a string returns a brand-new String instance, leaving the original unchanged.
Character Inspection & Bounds
Methods for inspecting character content and sequence boundaries:
| Method | Parameters | Return Type | Description / Notes |
|---|---|---|---|
length() | — | int | Number of character code units (instance method, not a field) |
charAt(int index) | int | char | Returns character at 0-based index; throws IndexOutOfBoundsException |
isEmpty() | — | boolean | Returns true if length() == 0 |
isBlank() | — | boolean | Returns true if empty or containing only whitespace characters (Java 11+) |
toCharArray() | — | char[] | Clones character content into a newly allocated char[] buffer |
codePointAt(int index) | int | int | Returns Unicode code point starting at index (handles supplementary emojis) |
String s = " Java DSA ";
System.out.println(s.length()); // 12
System.out.println(s.charAt(2)); // 'J'
System.out.println("".isEmpty()); // true
System.out.println(" ".isEmpty()); // false (length is 3)
System.out.println(" ".isBlank()); // true (Java 11+)Searching & Substrings
Methods for locating characters, substrings, or extracting slices:
| Method | Parameters | Return Type | Behavior / Contract |
|---|---|---|---|
indexOf(int ch) | int | int | First occurrence index of char/code point, or -1 if absent |
indexOf(String s) | String | int | First occurrence index of substring s, or -1 |
indexOf(String s, int from) | String, int | int | First occurrence index of s searching forward from from |
lastIndexOf(String s) | String | int | Last occurrence index of substring s, or -1 |
contains(CharSequence s) | CharSequence | boolean | Returns true if sequence exists anywhere within the string |
startsWith(String prefix) | String | boolean | Verifies whether the string begins with prefix |
endsWith(String suffix) | String | boolean | Verifies whether the string ends with suffix |
substring(int begin) | int | String | Extracts slice from begin through end of string |
substring(int begin, int end) | int, int | String | Extracts half-open slice [begin, end) |
String path = "src/main/App.java";
System.out.println(path.contains("main")); // true
System.out.println(path.startsWith("src/")); // true
System.out.println(path.endsWith(".java")); // true
int lastSlash = path.lastIndexOf('/');
String filename = path.substring(lastSlash + 1); // "App.java"
String extension = path.substring(path.lastIndexOf('.')); // ".java"Transformations & Tokenization
Every transformation method creates and returns a new String instance:
| Method | Parameters | Return Type | Description / Notes |
|---|---|---|---|
toLowerCase() / toUpperCase() | — | String | Converts all characters to lower/upper case |
trim() | — | String | Strips leading/trailing characters <= U+0020 (ASCII <= 32) |
strip() | — | String | Unicode-aware whitespace removal (Java 11+, preferred over trim()) |
stripLeading() / stripTrailing() | — | String | Removes whitespace only from start or end |
repeat(int count) | int | String | Repeats string count times (Java 11+) |
replace(CharSequence target, CharSequence replacement) | CharSequence, CharSequence | String | Replaces all exact literal matches |
replaceAll(String regex, String replacement) | String, String | String | Replaces all regular expression pattern matches |
replaceFirst(String regex, String replacement) | String, String | String | Replaces first regular expression match |
split(String regex) | String | String[] | Splits string around matching regex delimiters |
split(String regex, int limit) | String, int | String[] | Splits with resultant array size limit |
String.join(CharSequence delimiter, ...) | CharSequence, ... | String | Joins elements using a delimiter |
lines() | — | Stream<String> | Streams lines split by line terminators (Java 11+) |
The Regex Delimiter Trap: split(), replaceAll(), and replaceFirst() interpret their
first parameter as a regular expression! In regex, . matches any single character. Splitting
on . (s.split(".")) consumes every character and produces an empty array! java String ip = "192.168.1.1"; String[] bad = ip.split("."); // Produces empty array! (Trap) String[] good = ip.split("\\."); // Produces: ["192", "168", "1", "1"]
Splitting by Multiple Delimiters
To tokenize text by commas, spaces, or multiple consecutive delimiters:
String text = "apple, banana; orange grape";
// Split by comma, semicolon, or whitespace (1 or more occurrences)
String[] fruits = text.split("[,;\\s]+");
// Result: ["apple", "banana", "orange", "grape"]Formatting & Conversions
| Method | Parameters | Return Type | Usage |
|---|---|---|---|
String.valueOf(Object o) | Object / primitive | String | Safe string conversion; returns "null" if argument is null |
String.format(String fmt, ...) | String, Object... | String | Formats text with specifiers (%d, %s, %f, %02d) |
s.formatted(Object... args) | Object... | String | Instance formatting method (Java 15+) |
getBytes() | — | byte[] | Encodes string using platform default charset |
getBytes(Charset charset) | Charset | byte[] | Encodes with explicit charset (StandardCharsets.UTF_8) |
int score = 42;
double percentage = 93.456;
String message = String.format("User %s scored %d (%.2f%%)", "Alice", score, percentage);
// Output: "User Alice scored 42 (93.46%)"Alphabet Frequency Indexing (ch - 'a')
In competitive programming and string algorithms (e.g., Valid Anagram, First Unique Character), avoid using expensive HashMap<Character, Integer>. Instead, map lowercase characters a..z to array indices 0..25 using integer subtraction:
public static boolean isAnagram(String s, String t) {
if (s.length() != t.length()) return false;
int[] counts = new int[26];
for (int i = 0; i < s.length(); i++) {
counts[s.charAt(i) - 'a']++;
counts[t.charAt(i) - 'a']--;
}
for (int count : counts) {
if (count != 0) return false;
}
return true;
}Two-Pointer Palindrome Verification
Validating whether a string is a palindrome runs in O(n) time and O(1) space using inward two-pointer traversal:
public static boolean isPalindrome(String s) {
int left = 0;
int right = s.length() - 1;
while (left < right) {
// Skip non-alphanumeric characters
while (left < right && !Character.isLetterOrDigit(s.charAt(left))) left++;
while (left < right && !Character.isLetterOrDigit(s.charAt(right))) right--;
if (Character.toLowerCase(s.charAt(left)) != Character.toLowerCase(s.charAt(right))) {
return false;
}
left++;
right--;
}
return true;
}