0

我正在为一门课程编写代码。我们的目的是从用户指定的文件中扫描行,在每一行中搜索用户指定的一个或多个单词,并报告在整个文件中(逐行处理)这些单词出现的次数。我们分了三门课,打算写第四门课。我的代码在第 12 行抛出 NullPointerException,我不知道为什么。据我所见,我已经声明并初始化了该行中涉及的变量。我的代码是:

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());
    }
  }
}

堆栈跟踪:

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)

该应用程序的主要类如下。为了诊断问题,我已经注释掉了给定的代码并提供了我自己的代码。

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();
  }
}

此应用程序还使用 Echo 和 WordCount 类,如下所示:

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));
  }
}

我确实无法追踪异常的来源。我已经阅读了生成它的原因(本网站上有许多解释),但我无法诊断出我的实际代码中引发异常的原因。

非常感谢。

4

3 回答 3

6

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.

于 2013-04-11T23:54:49.423 回答
1

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();
        }   
      } 
于 2013-04-11T23:54:59.453 回答
1

看来您正试图在初始化之前将对象分配给 searchWords 数组(除非这是在超类中完成的)。确保你像初始化数组一样

WordCount[] wordArray = new WordCount[10];

或者

WordCount[] wordArray = new WordCount[]{new WordCount()};
于 2013-04-11T23:56:25.490 回答