5
\$\begingroup\$

I'm new to Java and is trying to solve the beginners problem of finding out the number of words in an user input string or a text file. I was just wondering if there are any alternatives to any of the steps that can improve efficiency as well as simplicity.

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Scanner;

public class WordsCount{
    public static void main(String[] args) {

        try(Scanner sc1 = new Scanner(System.in)){
            String userInputOrTextFile = sc1.next();
            if (userInputOrTextFile.equalsIgnoreCase("userInput")){
                WordsCount.countUserInput();
            } else {
                WordsCount.countTextFile();
            }
        }
    }

    private static void countUserInput() {
        try(Scanner sc1 = new Scanner(System.in)){
            String s1 = sc1.nextLine();
            System.out.println(s1.split(" ").length + " words in the user input sentence." );
        }
    }

    private static void countTextFile() {
        int countingWords = 0;
        try(Scanner sc1 = new Scanner(new BufferedReader(new FileReader("xanadu.txt")))){
            while(sc1.hasNext()){
                sc1.next();
                countingWords++;
            }
        } catch (FileNotFoundException e){
            System.out.println("File not found");
        }
        System.out.println(countingWords + " words are in the xanadu.txt file");
    }
}
\$\endgroup\$
5
\$\begingroup\$

Double Scanner usage

You use the scanner multiple times, this can create a few different bugs if the user scan input fet into the program using "userInput" mode. You should pass the scanner to the countUserInput, and remove the try-with-resources block from that method to prevent System.in from being closed.

Swallowing FileNotFoundException without printing its message

When opening the input file, you are swallowing a FileNotFoundException without printing its message.

This exception is also thrown under the following conditions:

  • When you try to open a directory as a file
  • Opening a file where you don't have read permissions for
  • The file doesn't exists

The best way to print a message would be:

catch(FileNotFoundException e){
    System.err.println("Error opening: " + e.getMessage());
}

This would show up as:

Error opening: C:/test.txt (Permission denied)

Bugs with large number of words

Your concurrent application overflows when counting at least 2147483647 words, by replacing the int with a long, you can support at least 9223372036854775807, a increase of 2^32.

Use a package name

While this may or may not be purposely left away, a package names groupes the code in an organization unit where everything can be found together, this also allows calls from other projects to your project.

|improve this answer|||||
\$\endgroup\$
5
\$\begingroup\$

On Regex use

To correctly split on white space and count the amount of words you want, use trim().split('\\s+').length

You want to split on all whitespace, not just a single ones in between, and you need to trim first because otherwise you'll also get inaccurate results for any input beginning with spaces.

This will also work just as well for your file input -- not too sure why you use a different method.

|improve this answer|||||
\$\endgroup\$

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.