Question: I have to reverse the string "He is the one" to "one the is He". I have written some programs in Java but am looking for other best solutions. Suggest any possible ways to minimize the current program.

First approach:

```
class StringRev{
    public static void main(String args[]){
    String str = "He is the one";
    String temp = "";
    String finalString = "";
        for(int i =str.length()-1;i>=0;i--){
            temp +=i!=0?str.charAt(i):str.charAt(i)+" ";
            if(str.charAt(i) == ' '||i==0){
                for(int j=temp.length()-1;j>=0;j--){
                    finalString += temp.charAt(j);
                }
                temp = "";
            }
        }
            System.out.println(finalString);
    }
}

```

Second approach:

```
class StringRev2{
    public static void main(String args[]){
    String str[] = "He is the one".split(" ");
    String finalStr="";
        for(int i = str.length-1; i>= 0 ;i--){
            finalStr += str[i]+" ";
        }
        System.out.println(finalStr);
    }
}

```

Answer: 
Stuffing all your code into `main()` is bad practice. This functionality belongs in a function of its own.

When doing multiple string concatenations, you really want to use a `StringBuilder`. If you don't, the compiler will make one for you anyway, *every time you concatenate two strings using +*. It's better to do it explicitly, then, and control how many of those temporary objects are created.

---

Your first approach works a character at a time. I suggest the following character-at-a-time approach, which allocates just one large temporary buffer.

```
private static void reverse(char[] buf, int start, int end) {
    for (int i = start, j = end - 1; i < j; i++, j--) {
        char swap = buf[i];
        buf[i] = buf[j];
        buf[j] = swap;
    }
}

public static String reverseWords1(String sentence) {
    char[] buf = sentence.toCharArray();

    // Reverse the string, character-wise
    reverse(buf, 0, buf.length);

    // Within each word, reverse the characters again
    int wordEnd = 0;
    for (int wordStart = 0; wordStart < buf.length; wordStart = wordEnd + 1) {
        for (wordEnd = wordStart; wordEnd < buf.length && buf[wordEnd] != ' '; wordEnd++) {}

        // wordStart is at the start of a word.
        // wordEnd is just past the end of the word.
        reverse(buf, wordStart, wordEnd);
    }
    return new String(buf);
}

```

---

I prefer your second approach, which is more succinct. Here it is, cleaned up by using a `StringBuilder`.

```
public static String reverseWords2(String sentence) {
    StringBuilder sb = new StringBuilder(sentence.length() + 1);
    String[] words = sentence.split(" ");
    for (int i = words.length - 1; i >= 0; i--) {
        sb.append(words[i]).append(' ');
    }
    sb.setLength(sb.length() - 1);  // Strip trailing space
    return sb.toString();
}

```
Here is a clean approach to reverse a string by its parts:

```
public class Main {

    // ReverseParts: reverses a string by words as opposed to characters.
    public static String ReverseParts(String input, String splitBy, String joinBy) {
        StringBuilder built = new StringBuilder();

        // Note: String.split uses regex. See its definition
        String[] list = input.split(splitBy);

        // Rejoin all the characters into a StringBuilder.
        for ( String part: list ) {
            built.insert(0, part);
            built.insert(0, joinBy);
        }

        // Remove the unnecessary 'joinBy bit'.
        built.delete(0, 1);

        // Get back the final string.
        return built.toString();
    }
    public static void main(String[] args) {
        final String input = "Hello  Johnny's World!";

        System.out.println("Result: '" + ReverseParts(input, " +", " ")+"'");
        // Output:
        // Result: 'World! Johnny's Hello'
    }
}

```