Java Invert String: StringBuilder.reverse() vs Character Iteration for Reversing Java Strings

Blurred multicolor Google logo letters formed by glowing circles.

Use StringBuilder.reverse() as the default way to invert a Java string. It is short, readable, tested by the JDK, and handles Unicode surrogate pairs better than a naïve character loop. Write your own character iteration only when you need custom behavior, strict allocation control, or educational clarity.

TLDR: For most Java applications, new StringBuilder(input).reverse().toString() is the safest and cleanest choice. For example, reversing "Java" returns "avaJ" with one readable line. In a typical service that reverses 50,000 short ASCII strings per request batch, a hand-written loop may save a small percentage in some benchmarks, but the maintenance cost is usually not worth it. If your strings may contain emoji, such as "A😊B", avoid simple char swapping unless you know exactly what you are doing.

Why string reversal in Java is less simple than it looks

Java strings are immutable. That means you cannot reverse a String in place. Every reversal creates a new text sequence in some form. This is true whether you use StringBuilder, a char[], or code point iteration.

The simple requirement sounds harmless: take "abcd" and return "dcba". The catch is that Java uses UTF-16 internally. Some visible characters need more than one char. Emoji, historic scripts, and some symbols are represented as surrogate pairs. If you reverse raw char values without care, you can corrupt those characters.

Line chart with yellow and blue data series showing rising values over time; data points labeled with numbers on a dark background.

Option 1: using StringBuilder.reverse()

The standard approach is direct:

public static String reverseWithStringBuilder(String input) {
    if (input == null) {
        return null;
    }
    return new StringBuilder(input).reverse().toString();
}

This method uses StringBuilder, a mutable sequence of characters. It copies the input, reverses the internal content, and returns a new String. The result is easy to read and hard to misunderstand.

Key benefits:

  • Readability: Any Java developer knows what the code does at a glance.
  • Reliability: The reverse logic is part of the JDK, not a custom utility that must be reviewed line by line.
  • Unicode safety: It handles valid surrogate pairs as single units during reversal.
  • Performance: It runs in linear time, O(n), which is optimal for this task.

For normal business code, this is the version you should prefer. It is not clever. That is a good thing. Production Java has enough surprises without hiding string reversal inside a hand-rolled loop.

Option 2: reversing by character iteration

A common manual implementation uses an array:

public static String reverseWithCharArray(String input) {
    if (input == null) {
        return null;
    }

    char[] chars = input.toCharArray();
    int left = 0;
    int right = chars.length - 1;

    while (left < right) {
        char temp = chars[left];
        chars[left] = chars[right];
        chars[right] = temp;
        left++;
        right--;
    }

    return new String(chars);
}

This is also O(n). It can be useful in coding interviews, tutorials, or performance experiments. It also gives you full control over how data is moved.

But there is a serious flaw: this version reverses individual UTF-16 char values. It does not understand Unicode code points. For plain ASCII text, that is fine. For emoji or supplementary characters, it can produce broken output.

Consider this example:

String input = "A😊B";

The smiley face is not stored as one Java char. It is stored as a surrogate pair. A naïve char reversal may split that pair and create invalid text. It drives me crazy that this bug often passes tests because the sample data only contains English letters.

Unicode correctness: char, code point, and grapheme

There are three levels to understand:

  • char: a 16-bit UTF-16 code unit.
  • Code point: a Unicode value, which may need one or two Java char values.
  • Grapheme cluster: what a user often sees as one character, such as a letter plus an accent or a joined emoji sequence.

StringBuilder.reverse() is better than naïve char swapping because it preserves surrogate pairs. That means "A😊B" becomes "B😊A", not broken text.

Yet even StringBuilder.reverse() is not a complete solution for every human writing system. It does not fully preserve every grapheme cluster. For example, combining marks can still surprise you. A letter such as may be stored as e plus a combining accent. Reversal can move the accent in a way that looks wrong.

3D-rendered hero showing the title 'Smartwriting Design Flows' with glossy white text on a curved dark screen and purple accents, surrounded by colorful shapes and emojis.

If you need reversal by user-perceived characters, use a Unicode-aware library such as ICU4J, or carefully test BreakIterator for your target languages and symbols. This matters in chat apps, names, search systems, and any product that accepts global user input.

Performance comparison

Both approaches are linear. For a string of length n, both must inspect or move characters. There is no magic shortcut.

In practical terms, StringBuilder.reverse() is usually fast enough. For short strings, the difference is noise. For long strings, memory allocation and copying become more visible than the loop itself.

A realistic JMH benchmark might show results like this on a modern JVM after warmup:

  • ASCII string, 32 characters: StringBuilder.reverse() and char[] reversal often differ by less than 10-15%.
  • ASCII string, 10,000 characters: manual array reversal can sometimes be slightly faster, depending on JVM and allocation behavior.
  • Unicode-heavy text: correctness matters more than raw speed, especially when surrogate pairs appear.

Do not benchmark this with System.currentTimeMillis() inside a loop and call it done. Use JMH. Warm up the JVM. Account for dead-code elimination. Otherwise, expect to waste time chasing numbers that change when you blink.

When to use StringBuilder.reverse()

Choose StringBuilder.reverse() when:

  • You are writing normal application code.
  • You want the clearest implementation.
  • Your input may contain emoji or supplementary Unicode characters.
  • You do not have measured proof that reversal is a bottleneck.
  • You want fewer custom bugs.

This should cover most backend services, desktop applications, Android utilities, tests, data processing scripts, and internal tools.

When character iteration makes sense

Manual iteration can still be valid. It is not wrong by default. It is just easier to get wrong.

Use a custom loop when:

  • You are demonstrating how reversal works.
  • You only process guaranteed ASCII or restricted character sets.
  • You need to reverse part of a buffer, not an entire string.
  • You are working in a tight loop and benchmarking proves a real gain.
  • You need custom rules, such as ignoring punctuation or preserving spaces.

For example, if a protocol field is guaranteed to contain only uppercase English letters from A to Z, a char[] loop is safe. In that narrow case, Unicode is not a concern.

A safer manual version using code points

If you want a custom reversal that handles supplementary characters, reverse by code point instead of by char:

public static String reverseByCodePoint(String input) {
    if (input == null) {
        return null;
    }

    int[] codePoints = input.codePoints().toArray();
    StringBuilder result = new StringBuilder(input.length());

    for (int i = codePoints.length - 1; i >= 0; i--) {
        result.appendCodePoint(codePoints[i]);
    }

    return result.toString();
}

This keeps surrogate pairs intact because it works with full Unicode code points. It may allocate more memory due to the int[]. It still may not preserve every grapheme cluster. But it is much safer than swapping raw char values.

UI panel showing network activity with red and green spikes on a dark background and a large orange Disconnect button at the bottom

Best practice recommendation

Default to StringBuilder.reverse(). It is concise, stable, and suitable for most Java string reversal needs. Use manual character iteration only when your input constraints are strict and documented.

If your application handles international text, test with real examples. Include emoji, combining accents, non-Latin scripts, and names from your user base. A reversal function that works for "hello" may still fail badly for real human text.

The practical rule is simple: prefer clarity first, measure before optimizing, and never assume one Java char equals one visible character. That rule will save bugs, review time, and awkward production fixes.