HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaModerate

Word count program in Java

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
countwordprogramjava

Problem

I am trying to write clean code in Java for reading text of any size and printing the word count in ascending order without using Java collection framework.

For example, given the following input text "What is the your name of the name?", it should print:

your 1
of 1
is 1
What 1
name 2
the 2


I have written the below code, but I am not sure it is the right answer. Please evaluate it.

```
public class WordArrayList {
private WordData[] words;
public void setWords(WordData[] words) {
this.words = words;
}
public WordData[] getWords() {
return words;
}
private int size;
public WordData getWord(int index) {
return words[index];
}
public int getSize() {
return size;
}
private static final int DEFAULT_WORD_ARRAY_SIZE = 10;
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
public WordArrayList() {
words = new WordData[DEFAULT_WORD_ARRAY_SIZE];
}
public WordArrayList(int initialCapacity) {
super();
if (initialCapacity MAX_ARRAY_SIZE) {
newCapacity = Integer.MAX_VALUE;
}
WordData[] newWords = new WordData[newCapacity];
System.arraycopy(words, 0, newWords, 0, size);
}
private boolean isWordArrayFull(int wordCount) {
return (wordCount - words.length > 0);
}
public void setWord(int i, WordData word) {
words[i] = word;
}

public class TextAnalyzer {

private static final String REG_SPLIT_EXP = "\\s+";
private String text;
private String textSplitExp;
private WordArrayList wordArrayList;

public TextAnalyzer(String text, String textSplitExp) {
this.textSplitExp = textSplitExp;
this.text = text;
wordArrayList = new WordArrayList();
}
public TextAnalyzer(String text) {
this.textSplitExp = REG_SPLIT_EXP;
this.text = text;
wordArrayList = new Word

Solution

There are a couple of things you should think about or fix:

-
Indentation. You're not really consistent in indenting your code. Please follow the Java conventions.

-
No need to call super() inside your constructor, the default empty super constructor is automatically called.

-
Use "constructor chaining" in WordArrayList, and TextAnalyzer. That is, call one constructor from another. For example,

public TextAnalyzer(String text) {
    this(text, REG_SPLIT_EXP);
}


-
You have a whole lot of unnecessary methods: setWords, getWords, setWordCount, setWord. You don't use them and I really don't think that you need them.

-
Use private final for fields that should be initialized once and then never change, such as private final String word; in the WordData class. Apply this wherever possible.

-
private int position; is not used in WordData, and I don't think you need to use it either. Select and press the Delete button on your keyboard

-
I suggest naming the class WordList instead. The fact that it uses an array is not important. It is a List of words, how the internal list works is not needed for the user to know

-
Calling generateWordArrayList multiple times would produce strange results.

-
convertToArray is private, contains one line, and is only called from one location: Does it really need to be it's own method?

-
Use a "for-each" loop to improve readability when iterating:

for (String str : splitTextArray)


-
You can store the number of times each word occurs with a HashMap instead. To initialize the HashMap, you can use this:

Map words = new HashMap();
for (String str : splitTextArray) {
    if (words.containsKey(str))
        words.put(str, words.get(str) + 1);
    else words.put(str, 1);
}


Note that you can use TreeMap instead of HashMap to keep the keys in a sorted order, so that if you iterate over words.entrySet(), you will always iterate in sorted order. (You can also provide a custom Comparator to the TreeMap if you are not satisfied with the built-in sorting)

Overall the current classes you have seems to do what they are supposed to do, and the result is correct. Good job.

Code Snippets

public TextAnalyzer(String text) {
    this(text, REG_SPLIT_EXP);
}
for (String str : splitTextArray)
Map<String, Integer> words = new HashMap<String, Integer>();
for (String str : splitTextArray) {
    if (words.containsKey(str))
        words.put(str, words.get(str) + 1);
    else words.put(str, 1);
}

Context

StackExchange Code Review Q#38767, answer score: 13

Revisions (0)

No revisions yet.