import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; /** * @author gtowell * Written: Jan 29, 2020 * * A small class that counts the number of uses of each word in a file. * This class illustrates the use of inner classes, ArrayList, readme, * and StringBuffer */ public class WordCounter { /** * Inner class to hold together the word and its count. */ private class WW { /** The word */ public final String word; /** The number of times the word is used in the document */ public int count; /** * Constructor initializing both word and count * * @param word the word * @param count the count. This is almost always zero */ public WW(String word, int count) { this.word = word; this.count = count; } /** * Simple string representation of the inner class. */ public String toString() { return word + ":" + count; } } /** An arrayList holding all of the Word and Count objects */ private ArrayList counts = new ArrayList<>(); public static void main(String[] args) { WordCounter wc = new WordCounter(); wc.countFile("ham.txt"); System.out.println(wc); } /** * Does most of the heavy lifting. Reads a file and fills in the counts * arraylist appropriately * * @param filename the name of the file to be read. */ void countFile(String filename) { try (BufferedReader br = new BufferedReader(new FileReader(filename));) { String line; while (null != (line = br.readLine())) { // read line and test if there is a line to read String[] ss = line.split("\\s+"); // split the line by spaces for (String token : ss) { // take the token i.e. word, lower case it, then get rid of punctuation token = token.toLowerCase().replace(".", "").replace(",", "").replace("?", "").replace("!", ""); if (token.length() > 0) { WW wordS = findWord(token); if (wordS == null) { // if have not already seen the word, add it to the arraylist wordS = new WW(token, 0); counts.add(wordS); } wordS.count++; // increment the number of times the word has been seen } } } } catch (FileNotFoundException e) { System.err.println("Error in opening the file:" + filename); System.exit(1); } catch (IOException ioe) { System.err.println("Error reading file " + ioe); System.exit(1); } } /** * Find a word in the list of seen words * * @param w the word to be found * @return the WW object containing the word. Or null if the word has not been * seen */ private WW findWord(String w) { for (WW aWord : counts) { if (aWord.word.equals(w)) return aWord; } return null; } public String toString() { // StringBuffer is a modifiable string. If you are changing a string a lot, it // is much more efficient. StringBuffer sb = new StringBuffer(); for (WW aWord : counts) { sb.append(aWord); sb.append("\n"); } sb.append("Distinct words: " + counts.size()); return sb.toString(); } }