Reverse a String in Java
Problem
Reversing a string means arranging its characters in the opposite order.
Given a string, reverse it and display the result.
Java Program
public class Main {
public static void main(String[] args) {
String str = "Hello Java";
String reversed = "";
// Walk backward from the last index to the first, appending each character
for (int i = str.length() - 1; i >= 0; i--) {
reversed += str.charAt(i);
}
System.out.println(reversed);
}
}Output
Core Logic
Walking backward through the string one character at a time and building up a new string as you go is the most direct way to reverse it.
- 1Start at the last index —
length() - 1— since string indices run from 0 to length-1. - 2Loop backward, decrementing
iby one on each pass. - 3At each step,
charAt(i)reads the character and appends it toreversed. - 4The loop stops once
idrops below 0, having visited every character exactly once. - 5
reversednow holds the string with its characters in the opposite order.
"Hello Java", the loop appends 'a', 'v', 'a', 'J', ' ', 'o', 'l', 'l', 'e', 'H' in turn — producing "avaJ olleH".Key Point: This approach runs in O(n) time; for very long strings, StringBuilder.reverse() avoids repeated string concatenation and performs better.
Why: Every character is visited once and appended onto the growing reversed string, whose final length matches the original.
Key Concepts
Approach 2: StringBuilder.reverse()
public class ReverseStringBuilder {
public static void main(String[] args) {
String str = "Hello Java";
// reverse() flips the buffer's characters in place; toString() converts it back
String reversed = new StringBuilder(str).reverse().toString();
System.out.println(reversed);
}
}
Output
Core Logic
Skip the manual loop altogether — StringBuilder already has a reverse() method built in, and it's what you'd actually reach for in real code.
- 1
new StringBuilder(str)wraps the string in a mutable character buffer. - 2
.reverse()flips the buffer's character order in place. - 3
.toString()converts the reversed buffer back into a regularString.
"Hello Java", new StringBuilder("Hello Java").reverse().toString() produces "avaJ olleH" in a single expression.Key Point: StringBuilder.reverse() is implemented internally with an in-place array swap, so it's both shorter to write and faster than repeated string concatenation.
Why: The internal buffer's characters are swapped end-to-end in a single pass, and that buffer holds all n characters at once.
Key Concepts
Approach 3: Recursion
public class ReverseStringRecursive {
static String reverse(String str) {
// Base case: an empty string is its own reverse
if (str.isEmpty()) return str;
// Move the first character to the end of the reversed remainder
return reverse(str.substring(1)) + str.charAt(0);
}
public static void main(String[] args) {
String str = "Hello Java";
System.out.println(reverse(str));
}
}
Output
Core Logic
Recursion offers a different angle: peel off the first character, reverse everything after it, then tack that first character onto the end.
- 1The base case
if (str.isEmpty()) return str;stops the recursion once there are no characters left. - 2Every other call splits the string into its first character,
str.charAt(0), and the rest,str.substring(1). - 3It returns
reverse(str.substring(1)) + str.charAt(0)— the reversed remainder, with the first character moved to the end. - 4As the recursion unwinds, each character gets appended in the opposite order it was removed.
reverse("Hi") becomes reverse("i") + 'H', and reverse("i") becomes reverse("") + 'i' → "i", so the final result is "i" + "H" = "iH".Key Point: This is elegant but not efficient — substring() and string concatenation each allocate a new String, making it O(n²) overall, unlike the O(n) loop or StringBuilder versions.
Why: Each call allocates a new substring of decreasing length and concatenates a character onto it, so the total work across all n calls adds up quadratically.
Key Concepts
Approach 4: Java 8
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class ReverseStringStream {
public static void main(String[] args) {
String str = "Hello Java";
// Maps each index to the character at its mirrored position, then joins them back up
String reversed = IntStream.range(0, str.length())
.mapToObj(i -> str.charAt(str.length() - 1 - i))
.map(String::valueOf)
.collect(Collectors.joining());
System.out.println(reversed);
}
}
Output
Core Logic
A string's characters can be streamed, walked in reverse index order, and joined back together — no loop or recursion needed.
- 1
IntStream.range(0, str.length())produces every valid index into the string. - 2
.mapToObj(i -> str.charAt(str.length() - 1 - i))maps each index to the character at its mirrored position from the end, the same idea the loop's backward walk used. - 3
.map(String::valueOf)converts eachcharinto a one-characterString, since streams of primitives can't be joined directly. - 4
.collect(Collectors.joining())concatenates all the mapped characters back into a singleString.
"Hello Java", index 0 maps to the last character 'a', index 1 maps to 'v', and so on, joining back into "avaJ olleH".Key Point: This is a more roundabout way to reverse a string than StringBuilder.reverse() — it exists mainly to show that the same result is reachable with a pure stream pipeline, not because it's the best tool for the job.
Why: Each index is mapped to its mirrored character in one pass, and Collectors.joining() builds a result string holding all n characters.
Key Concepts
Common Mistakes
- Using
str += str.charAt(i)inside a loop is fine for short strings, but for large inputs it's slow — each+=creates a brand-newString, since strings are immutable.StringBuilderavoids that. - Forgetting the loop bound is
str.length() - 1, notstr.length()— the last valid index is always one less than the length.
Interview Questions
Can you reverse a string in Java without StringBuilder?
Yes. Walk the string from the last index down to 0 and append each character to a new string, or copy it into a char[] and swap characters from both ends with two pointers. The two-pointer version does the work in place on the array, then new String(chars) turns it back into text.
Why doesn't Java's String class have a reverse() method?
String is immutable, so any "reverse" would have to create a new object anyway. Java puts mutating operations such as reverse(), insert() and deleteCharAt() on StringBuilder, which is designed for building and changing text.
Does reversing a string work correctly with emoji?
Not always. Many emoji are stored as two char values (a surrogate pair), and a naive character-by-character reverse splits them into invalid characters. StringBuilder.reverse() handles surrogate pairs correctly, which is one more reason to prefer it in real code.