1
\$\begingroup\$

I have been coding in Java for about a month now and I'm seeking advice for my program on things I can improve. This project was mainly made for me to incorporate all the new things I learned and utilize them effectively. I appreciate any feedback :).

About the program itself, it takes in a string and reverses it. It also counts the amount of characters (spaces, numbers, letters, and other characters) and it checks if the typed string is a palindrome or not.

Main class

public class Main {
    
    public static void main(String[] args) {
        Application application = new Application();
        
        application.printInstructions();
        application.programLoop();
        application.printSeparator(); // Prints a separator before the program terminates.
    }
}

Application class

import java.util.Scanner;

public class Application {
    Scanner userInput = new Scanner(System.in);
    String definedString;

    // Main function for reversing the string.
    private String reverseString(String string) {
        StringBuilder stringBuilder = new StringBuilder();
        char[] charArray = string.toCharArray();
        for (int i = string.length() - 1; i >= 0; i--) {
            stringBuilder.append(charArray[i]);
            
        }
        
        return stringBuilder.toString();
    }

    // Processes the output and prints it out.
    private void processInput() {
        
        printSeparator();
        System.out.println("Reversed String: " + reverseString(definedString));
        printSeparator();
        
        countCharacters(definedString);
        isPalindrome();
        programLoop();
        
    }

    // Main program loop.
    public boolean programLoop() {
        System.out.print("-: ");
        definedString = userInput.nextLine();
        
        // If the input isn't the break command, it processes and prints out the results.
        while (!definedString.equals("!break")) {
            processInput();
            
        }
        
        return false;
        
    }

    // Prints starting instructions.
    public void printInstructions() {
        System.out.println("StringModifier - Reverses a string and returns information about it.");
        System.out.println("Type '!break' to exit");
        
    }

    // Counts the amount of characters in the reversed string.
    private void countCharacters(String string) {
        char[] charArray = string.toCharArray();
        int letters = 0;
        int numbers = 0;
        int spaces = 0;
        int other = 0;

        for (int i = 0; i < string.length(); i++) {
            if (Character.isSpaceChar(charArray[i])) {
                spaces++;

            } else if (Character.isDigit(charArray[i])) {
                numbers++;

            } else if (Character.isLetter(charArray[i])) {
                letters++;

            } else {
                other++;

            }
        }
        
        System.out.println("Spaces: " + spaces);
        System.out.println("Numbers: " + numbers);
        System.out.println("Letters: " + letters);
        System.out.println("Other: " + other);
    }
    
    // Adds a separating line.
    public void printSeparator() {
        System.out.println("—————————————————————————————————————");
        
    }
    
    // Checks if the string is a palindrome.
    public void isPalindrome() {
        
        if (definedString.equals(reverseString(definedString))) {
            System.out.println("Is a Palindrome: Yes");
        } else {
            System.out.println("Is a Palindrome: No");
        }
    }

}
\$\endgroup\$
2
\$\begingroup\$

You should rewrite your reverseString to use the built-in StringBuilder.reverse().

Your class structure is a little bit mixed up. The Application and Main classes currently have some of the same obligations. Rephrase this to, perhaps,

  • a Main class that only cares about display and does your program loop
  • a StringInfo class that does no integrated display in its logic methods, and has accessor functions for reversed (returning a string and not printing), isPalindrome (returning a boolean and not printing), spaceCount (returning an integer and not printing), etc.

Suggested

import java.util.Scanner;

public class Main {
    final Scanner userInput = new Scanner(System.in);

    public static void main(String[] args) {
        Main app = new Main();

        printInstructions();
        app.programLoop();
        printSeparator();
    }

    // Prints starting instructions.
    public static void printInstructions() {
        System.out.println("StringModifier - Reverses a string and returns information about it.");
        System.out.println("Type '!break' to exit");
    }

    // Main program loop.
    public void programLoop() {
        // If the input isn't the break command, it processes and prints out the results.
        while (true) {
            printSeparator();
            System.out.print("-: ");
            String definedString = userInput.nextLine();
            if (definedString.equals("!break"))
                break;
            (new StringInfo(definedString)).dump();
        }
    }

    // Adds a separating line.
    public static void printSeparator() {
        System.out.println("—————————————————————————————————————");
    }
}

public class StringInfo {
    public final String definedString;

    public StringInfo(String definedString) {
        this.definedString = definedString;
    }

    public String reversed() {
        StringBuilder builder = new StringBuilder(definedString);
        builder.reverse();
        return builder.toString();
    }

    public long nSpaces() {
        return definedString.chars().filter(ch -> Character.isSpaceChar(ch)).count();
    }

    public long nLetters() {
        return definedString.chars().filter(ch -> Character.isLetter(ch)).count();
    }

    public long nDigits() {
        return definedString.chars().filter(ch -> Character.isDigit(ch)).count();
    }

    public long nOther() {
        return definedString.chars().filter(ch -> !(
               Character.isSpaceChar(ch)
            || Character.isLetter(ch)
            || Character.isDigit(ch)
        )).count();
    }

    public boolean isPalindrome() {
        return definedString.equals(reversed());
    }

    public void dump() {
        System.out.printf("Reversed String: %s%n", reversed());
        System.out.printf("Spaces: %d%n", nSpaces());
        System.out.printf("Digits: %d%n", nDigits());
        System.out.printf("Letters: %d%n", nLetters());
        System.out.printf("Other: %d%n", nOther());

        System.out.print("Is a palindrome: ");
        if (isPalindrome()) System.out.println("yes");
        else System.out.println("no");
    }
}
\$\endgroup\$
3
  • \$\begingroup\$ Thank you for your feedback! I do have one question though. Why is it preferable to use return statements instead of just printing it out from the method? My thought is to probably have flexible values which I can use anywhere in my program. \$\endgroup\$ Jul 22 at 6:51
  • 1
    \$\begingroup\$ @Kimosauraus Why prefer return over printing? Because you might want to re-use things like string reverting or character counting later in a program with a GUI, or in a web server or whatever. Make it a habit to separate information processing from input/output. \$\endgroup\$ Jul 22 at 11:47
  • \$\begingroup\$ Ah, I see. Thank you for your answer. \$\endgroup\$ Jul 22 at 11:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.