Reputation: 516
I am writing code for a course. We are meant to scan lines from a file specified by the user, search each line for one or more words specified by the user, and report how many times in the whole file (having processed line by line) these words are present. We are given three classes, and meant to write the fourth. My code is throwing a NullPointerException on line 12, and I'm not sure why. As far as I can see I have both declared and initialized the variables involved in that line. My code is:
import java.io.IOException;
import java.util.*;
public class WordFreq extends Echo{
String[] searchWordsAsStrings;
WordCount[] searchWords;
public WordFreq(String f, String w) throws IOException{
super(f);
searchWordsAsStrings = w.split(" ");
for(int a = 0; a < searchWordsAsStrings.length; a++){
searchWords[a] = new WordCount("");
}
for(int a = 0; a < searchWordsAsStrings.length; a++){
searchWords[a].setWord(searchWordsAsStrings[a]);
}
}
public void processLine(String line){
StringTokenizer st = new StringTokenizer(line);
while(st.hasMoreTokens()){
for(int a = 0; a < searchWords.length; a++){
if(searchWords[a].getWord() == st.nextToken()){
searchWords[a].incCount();
}
}
}
}
public void reportFrequencies(){
System.out.println("Word counts:");
for(int a = 0; a < searchWords.length; a++){
System.out.println(searchWords[a].toString());
}
}
}
Stack trace:
java.lang.NullPointerException
at WordFreq.<init>(WordFreq.java:12)
at FreqStudy.main(FreqStudy.java:20)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at edu.rice.cs.drjava.model.compiler.JavacCompiler.runCommand(JavacCompiler.java:272)
The main class of this application is below. I have commented out the given code and provided my own, in an effort to diagnose the problem.
import java.util.*;
import java.io.*;
public class FreqStudy{
public static void main(String[] args) throws IOException
{
/*
Scanner scan = new Scanner(System.in);
System.out.println("enter file name");
String fileName = scan.next();
*/
String fileName = "pg37997.txt";
/*
Scanner scan2 = new Scanner(System.in);
System.out.println("enter words to search for");
System.out.println("enter lower case, separated by spaces");
String wordString = scan2.nextLine();
*/
String wordString = "cow horse chicken goat pig";
WordFreq f = new WordFreq(fileName,wordString);
f.readLines();
f.reportFrequencies();
}
}
This application also uses the Echo and WordCount classes, provided below:
import java.util.Scanner;
import java.io.*;
public class Echo{
String fileName; // external file name
Scanner scan; // Scanner object for reading from external file
public Echo(String f) throws IOException
{
fileName = f;
scan = new Scanner(new FileReader(fileName));
}
public void readLines(){ // reads lines, hands each to processLine
while(scan.hasNext()){
processLine(scan.nextLine());
}
scan.close();
}
public void processLine(String line){ // does the real processing work
System.out.println(line);
}
}
public class WordCount{
private String word;
private int count;
public WordCount(String w){
word = w;
count = 0;
}
public String getWord(){
return word;}
public void setWord(String w){
word = w;
}
public int getCount(){
return count;}
public void incCount(){count++;}
public String toString() {
return(word + " --- " + count);
}
public boolean equals(Object other){
WordCount i = (WordCount)other;
return (this.word.equals(i.word));
}
}
I well and truly cannot trace where the exception is coming from. I've read up on what generates it (many explanations on this site) but I cannot diagnose what in my actual code is throwing the exception.
Many thanks.
Upvotes: 0
Views: 457
Reputation: 24910
Your WordCount[] searchWords;
array never gets initialized.
Add a searchWords = new WorkCount[searchWorkdsAsStrings.length];
under searchWordsAsStrings = w.split(" ");
EDIT
To answer your question from comment below, the st.nextToken() advances the token and this is what is throwing your NoSuchElementException. Instead of doing that inside your for loop, read the st.nextToken() into a variable and then do your == comparison.
while(st.hasMoreTokens()){
String s = st.nextToken();
for(int a = 0; a < searchWords.length; a++){
if(searchWords[a].getWord().equals(s)){
searchWords[a].incCount();
}
}
Upvotes: 1
Reputation: 111
It appears that you are attempting to assign objects to the searchWords array before it is initialized (unless this is done in the super class). Make sure you initialize the array like
WordCount[] wordArray = new WordCount[10];
or
WordCount[] wordArray = new WordCount[]{new WordCount()};
Upvotes: 1
Reputation: 27336
Your issue is because of an improperly initialised array!
WordCount[] searchWords;
But you never declare searchWords = new WordCount[dimension];
When you attempt to reference this array, you're trying to access something that doesn't exist. Because WordCount[]
is an object in, and of, itself, it is throwing a NullPointerException
because it does not yet reference a WordCount[]
object.
Upvotes: 6