Main Tutorials

How to reverse a string in Java

StringBuilder reverse API

In this article, we will show you a few ways to reverse a String in Java.

  • StringBuilder(str).reverse()
  • char[] looping and value swapping.
  • byte looping and value swapping.
  • Apache commons-lang3

For development, always picks the standard StringBuilder(str).reverse() API.

For educational purposes, we can study the char[] and byte methods, it involved value swapping and bitwise shifting techniques that are very useful to understand what is happening behind the reverse API black box.

1. StringBuilder(str).reverse()

In Java, we can use StringBuilder(str).reverse() to reverse a String.

ReverseString1.java

package com.mkyong.crypto.bytes;

public class ReverseString1 {

    public static void main(String[] args) {

        String str = "Reverse a String in Java";

        StringBuilder sb = new StringBuilder(str).reverse();

        System.out.println(sb.toString());

    }

}

Output

Terminal

  avaJ ni gnirtS a esreveR

2. Char[]

First, we convert the string into a char array and loop the char array one by one and swap values using a temp variable.

ReverseString2.java

package com.mkyong.utils;

public class ReverseString2 {

    public static void main(String[] args) {

        String str = "Hello World";
        System.out.println(reverse(str));         //  dlroW olleH

    }

    public static String reverse(String input) {

        if (input == null || input.length() < 0)
            throw new IllegalArgumentException("Please provide an input!");

        char[] result = input.toCharArray();

        int startIndex = 0;
        int endIndex = result.length - 1;
        char temp;

        for (; endIndex > startIndex; startIndex++, endIndex--) {
            temp = result[startIndex];
            result[startIndex] = result[endIndex];
            result[endIndex] = temp;
        }

        return new String(result);
    }

}

The above algorithm needs 5 loops (length/2) to reverse a string "Hello World".


------------------------------------
H  e  l  l  o     W  o  r  l  d
------------------------------------
0  1  2  3  4  5  6  7  8  9  10
------------------------------------

Loop #1 - Swap index 0 <-> index 10
------------------------------------
{d}  e  l  l  o     W  o  r  l  {H}
------------------------------------
{0}  1  2  3  4  5  6  7  8  9  {10}
------------------------------------

Loop #2 - Swap index 1 <-> index 9
------------------------------------
d  {l}  l  l  o     W  o  r  {e}  H
------------------------------------
0  {1}  2  3  4  5  6  7  8  {9}  10
------------------------------------

Loop #3 - Swap index 2 <-> index 8
------------------------------------
d  l  {r}  l  o     W  o  {l}  e  H
------------------------------------
0  1  {2}  3  4  5  6  7  {8}  9  10
------------------------------------

Loop #4 - Swap index 3 <-> index 7
------------------------------------
d  l  r  {o}  o     W  {l}  l  e  H
------------------------------------
0  1  2  {3}  4  5  6  {7}  8  9  10
------------------------------------

Loop #5 - Swap index 4 <-> index 6
------------------------------------
d  l  r  o  {W}     {o}  l  l  e  H
------------------------------------
0  1  2  3  {4}  5  {6}  7  8  9  10
------------------------------------

3. Byte[] – StringBuilder(str).reverse()

The below code snippet is similar to the StringBuilder(str).reverse() to reverse a string (excepts UTF16 stuff).

ReverseString3.java

package com.mkyong.crypto.bytes;

import java.nio.charset.StandardCharsets;

public class ReverseString3 {

    public static void main(String[] args) {

        String str = "Hello World";
        System.out.println(reverse(str));

    }

    public static String reverse(String input) {

        if (input == null || input.length() < 0)
            throw new IllegalArgumentException("Please provide an input!");

        byte[] val = input.getBytes(StandardCharsets.UTF_8);
        int length = val.length - 1;

        for (int start = (length - 1) >> 1; start >= 0; start--) {
            int end = length - start;
            byte temp = val[start];
            val[start] = val[end];
            val[end] = temp;

            // debugging
            //System.out.println(String.format("start=%s, end=%s", start, end));
        }

        return new String(val);
    }

}

The most confusing part is the bit right shift operator (length - 1) >> 1, what does it mean?

Review the following 8 bits example, can you find out the pattern?


System.out.println(10>>1);  //  10 -> 5
0000 1010   = 10
0000 0101|0 = 10 >> 1 = 5

System.out.println(4>>1);   //  4 -> 2
0000 0100   = 4
0000 0010|0 = 4 >> 1 = 2

System.out.println(100>>1); //  100 -> 50
0110 0100   = 100
00110 010|0 = 100 >> 1 = 50

System.out.println(7>>1);   //  7 -> 3
0000 0111   = 7
0000 0011|1 = 7 >> 1 = 3

For number, every right shift by 1 bit, the amount will drop half of the value and round down. This (length - 1) >> 1 tries to find out the middle point of the string.


number >> 1 = round_down(number/2) or Math.flooa(number/2)

And the value swapping is starting from the inside and expand to outside.


  for (int start = (length - 1) >> 1; start >= 0; start--) {
      int end = length - start;
      byte temp = val[start];
      val[start] = val[end];
      val[end] = temp;
  }

------------------------------------
H  e  l  l  o     W  o  r  l  d
------------------------------------
0  1  2  3  4  5  6  7  8  9  10
------------------------------------

Loop #1 - Swap index 4 <-> index 6
------------------------------------
H  e  l  l  {W}     {o}  o  r  l  d
------------------------------------
0  1  2  3  {4}  5  {6}  7  8  9  10
------------------------------------

Loop #2 - Swap index 3 <-> index 7
------------------------------------
H  e  l  {o}  W     o  {l}  r  l  d
------------------------------------
0  1  2  {3}  4  5  6  {7}  8  9  10
------------------------------------

Loop #3 - Swap index 2 <-> index 8
------------------------------------
H  e  {r}  o  W     o  l  {l}  l  d
------------------------------------
0  1  {2}  3  4  5  6  7  {8}  9  10
------------------------------------

Loop #4 - Swap index 1 <-> index 9
------------------------------------
H  {l}  r  o  W     o  l  l  {e}  d
------------------------------------
0  {1}  2  3  4  5  6  7  8  {9}  10
------------------------------------

Loop #5 - Swap index 0 <-> index 10
------------------------------------
{d}  l  r  o  W     o  l  l  e  {H}
------------------------------------
{0}  1  2  3  4  5  6  7  8  9  {10}
------------------------------------

4. Apache commons-lang3

For Apache commons-lang3 library, we can use StringUtils.reverse to reverse a string, and StringUtils.reverseDelimited to reverse words.

pom.xml

  <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-lang3</artifactId>
      <version>3.10</version>
  </dependency>
ReverseString3.java

package com.mkyong.utils;

import org.apache.commons.lang3.StringUtils;

public class ReverseString3 {

    public static void main(String[] args) {

        System.out.println(StringUtils.reverse("Hello World Java"));                // reverse string

        System.out.println(StringUtils.reverseDelimited("Hello World Java", ' '));  // reverse words

    }
}

Output

Terminal

avaJ dlroW olleH

Java World Hello

Review the source code, internally, the Apache commons-lang3 is using the new StringBuilder(str).reverse() to reverse the string.

StringUtils.java

package org.apache.commons.lang3;

  public class StringUtils {

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

  //...
}

References

About Author

author image
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities.

Comments

Subscribe
Notify of
0 Comments
Inline Feedbacks
View all comments