dfaulken
dfaulken

Reputation: 516

Trying to diagnose NullPointerException

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

Answers (3)

Kal
Kal

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

ntaylor2
ntaylor2

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

christopher
christopher

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

Related Questions