How to Reverse a String in Java
Reverse a Java string with StringBuilder.reverse, character arrays, recursion, or streams.
How to Reverse a String in Java
Reversing a string means producing a new string whose characters appear in the opposite order — "Hello" becomes "olleH". Java strings are immutable, so you never reverse a string in place; you build a new one. There are several idiomatic ways to do it, and the right choice depends on whether you want the shortest code, the fewest dependencies, or correct handling of characters outside the basic plane.
The idiomatic way: StringBuilder.reverse
The standard library already has a reverse method on StringBuilder (and StringBuffer). It is the answer in almost every situation:
String reversed = new StringBuilder("Hello").reverse().toString();
// reversed = "olleH"Wrap the original string in a StringBuilder, call reverse(), and call toString() to get a plain String back. This is fast (a single pass, no boxing) and reads clearly. A nice bonus: StringBuilder.reverse() is surrogate-aware — it keeps the two chars of a supplementary code point (such as an emoji) together instead of flipping them and producing garbage.
Manual loop over a char array
When you want to see the mechanics — or you are in an environment where you cannot use StringBuilder — walk a char[] from the last index down to the first:
char[] chars = "Hello".toCharArray();
StringBuilder out = new StringBuilder();
for (int i = chars.length - 1; i >= 0; i--) {
out.append(chars[i]);
}
String reversed = out.toString();This is exactly what StringBuilder.reverse does internally, minus the surrogate handling. Avoid building the result with reversed += chars[i] on a bare String: string concatenation in a loop creates a new object each iteration and turns an O(n) job into O(n²).
Recursion and streams
A recursive solution reads like its definition — the reverse of a string is the reverse of its tail followed by its first character:
static String reverse(String s) {
if (s.isEmpty()) return s;
return reverse(s.substring(1)) + s.charAt(0);
}It is elegant but allocates a substring per call and can overflow the stack on very long input, so treat it as a teaching tool rather than production code. A stream-based one-liner avoids recursion but is the least readable of the bunch:
String reversed = "Hello".chars()
.mapToObj(c -> String.valueOf((char) c))
.reduce("", (a, b) -> b + a);| Approach | Lines | Speed | Surrogate-safe |
|---|---|---|---|
StringBuilder.reverse | 1 | Fast | Yes |
| Manual char-array loop | ~5 | Fast | No |
| Recursion | ~4 | Slow, stack-bound | No |
| Stream + reduce | ~3 | Slow (rebuilds string) | No |
A worked example
This program reverses "Hello" four different ways, confirms they all agree, then checks two edge cases: an empty string and a string containing an emoji (a surrogate pair).
What to take from the run:
- All four approaches print
olleH, so they are interchangeable for plain ASCII text — the choice between them is about readability and performance, not correctness. StringBuilder.reverseproduced the result in a single expression, which is why it is the default recommendation over the loop, recursion, and stream variants.- Reversing the empty string returns the empty string (
''), confirming the methods are safe to call without a length check — no special-casing needed. - The recursive
reverseterminated because its base case (s.isEmpty()) stops the chain ofsubstring(1)calls; without that guard it would never return. naive emoji ok: trueshowsStringBuilder.reversekept the grinning-face emoji intact — it moved the surrogate pair as a unit. A hand-rolledchar-by-charloop would split that pair and corrupt the emoji.
Practice
Which built-in method reverses a string in one expression and also keeps surrogate pairs (such as emoji) intact?