Java Programs›Strings›Reverse a String

Reverse a String in Java

beginner·  Strings  ·  String Manipulation

Problem

Reversing a string means arranging its characters in the opposite order.

Given a string, reverse it and display the result.

Input
Hello Java
Output
avaJ olleH

Java Program

Java
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

avaJ olleH

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.

How It Works
  1. 1Start at the last index — length() - 1 — since string indices run from 0 to length-1.
  2. 2Loop backward, decrementing i by one on each pass.
  3. 3At each step, charAt(i) reads the character and appends it to reversed.
  4. 4The loop stops once i drops below 0, having visited every character exactly once.
  5. 5reversed now holds the string with its characters in the opposite order.
For "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.

Complexity
Time Complexity: O(n)Space Complexity: O(n)

Why: Every character is visited once and appended onto the growing reversed string, whose final length matches the original.

Key Concepts

Stringlength()charAt()for loop

Approach 2: StringBuilder.reverse()

Java
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

avaJ olleH

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.

How It Works
  1. 1new StringBuilder(str) wraps the string in a mutable character buffer.
  2. 2.reverse() flips the buffer's character order in place.
  3. 3.toString() converts the reversed buffer back into a regular String.
For "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.

Complexity
Time Complexity: O(n)Space Complexity: O(n)

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

StringBuilderreverse()method chaining

Approach 3: Recursion

Java
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

avaJ olleH

Core Logic

Recursion offers a different angle: peel off the first character, reverse everything after it, then tack that first character onto the end.

How It Works
  1. 1The base case if (str.isEmpty()) return str; stops the recursion once there are no characters left.
  2. 2Every other call splits the string into its first character, str.charAt(0), and the rest, str.substring(1).
  3. 3It returns reverse(str.substring(1)) + str.charAt(0) — the reversed remainder, with the first character moved to the end.
  4. 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.

Complexity
Time Complexity: O(n²)Space Complexity: O(n)

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

recursionsubstring()base case

Approach 4: Java 8

Java
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

avaJ olleH

Core Logic

A string's characters can be streamed, walked in reverse index order, and joined back together — no loop or recursion needed.

How It Works
  1. 1IntStream.range(0, str.length()) produces every valid index into the string.
  2. 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. 3.map(String::valueOf) converts each char into a one-character String, since streams of primitives can't be joined directly.
  4. 4.collect(Collectors.joining()) concatenates all the mapped characters back into a single String.
For "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.

Complexity
Time Complexity: O(n)Space Complexity: O(n)

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

Streamchars()Collectors.joining()

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-new String, since strings are immutable. StringBuilder avoids that.
  • Forgetting the loop bound is str.length() - 1, not str.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.

Learn the Concept

Related Programs