I wrote a program that reads a text file and then outputs the unique words, their frequency, and the line numbers that word appears on. It also counts the number of sentences in the text file. All of this information is then outputted to a text file.
I currently have all of the code in one class object. What would be the correct way to divide up the functions / code so that I use OOP correctly? I have been reading up on separation of concerns but am having trouble applying it to this program. Should I make the code that handles input 1 separate class? Followed by a class for the "word tracking"? Then another class for output? Feel free to be as blunt as you like, I know it's not very good as is but I really want to improve it. I want to become better at implementing best practices of OOP in my programs.
class WordInfo
{
private int sentenceTotal;
LineNumberReader br = null;
BufferedWriter bw = null;
Map<String, ArrayList<Integer>> map = new TreeMap<String, ArrayList<Integer>>();
public WordInfo (int sens)
{
sentenceTotal = sens;
}
private void updateSenTotal(int curSens)
{
sentenceTotal += curSens;
}
private void sentenceCount(String sen1)
{
String senString = sen1;
int sCounts = 0;
String[] sCounter = senString.split("[.|?|!]");
for (String counts : sCounter)
{
if(!counts.equals(" "))
{
sCounts++;
}
}
sentenceTotal+=sCounts;
}
public void wordTrack()
{
String currentLine = null;
try
{
while ((currentLine = br.readLine()) != null)
{
if (!currentLine.isEmpty())
{
String senString = currentLine.toLowerCase();
sentenceCount(currentLine);
String[]parts = senString.split("\\W");
for (String prints : parts)
{
// if the map does not contain the word, the word is added to the map and
// an array list of integers is also created for that key's value and
// a value of 1 is put into the arraylist to count the frequency of the word
// A line number value is also added to the arraylist at index 1.
if (!map.containsKey(prints) && !prints.equals("") && prints.length() != 1)
{
ArrayList<Integer> inter = map.get(prints);
inter = new ArrayList<Integer>();
map.put(prints, inter);
inter.add(1);
inter.add(br.getLineNumber());
}
// if the map already contains the word, then the frequency of the word is
// incremented by 1 and the line number where the word was found is added to the list.
else if (map.containsKey(prints))
{
int adder = map.get(prints).get(0);
adder += 1;
map.get(prints).set(0, adder);
map.get(prints).add(br.getLineNumber());
}
}
}
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
public void fileIn(String fileName)
{
String name = fileName;
try
{
br = new LineNumberReader(new FileReader(name));
}
catch (IOException e)
{
e.printStackTrace();
}
}
public void fileOut(String fileName)
{
String name = fileName;
try
{
bw = new BufferedWriter(new FileWriter(name));
}
catch (IOException e)
{
e.printStackTrace();
}
}
public void printFile()
{
try {
for (String printKey : map.keySet())
{
bw.write(printKey + " | " + map.get(printKey).get(0) + " | ");
for(int i = 1; i < map.get(printKey).size(); i++)
{
// if statement to ensure that when the final line number in the arraylist
// is written to the file it is not followed by a comma
if(i != map.get(printKey).size() - 1)
bw.write(map.get(printKey).get(i) + ", ");
else
bw.write(map.get(printKey).get(i) + "");
}
bw.write("\n");
}
bw.write("\nSentence count: " + sentenceTotal);
bw.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
public class OOPQuestion {
public static void main(String[] args) throws IOException
{
WordInfo info = new WordInfo(0);
info.fileIn("/Users/Chris/Desktop/testingInput.txt");
info.fileOut("/Users/Chris/Desktop/testOutput.txt");
info.wordTrack();
info.printFile();
System.out.println("Count complete");
}
}