0

コースのコードを書いています。ユーザーが指定したファイルから行をスキャンし、ユーザーが指定した 1 つまたは複数の単語を各行で検索し、ファイル全体 (行ごとに処理して) にこれらの単語が何回存在するかを報告します。3 つのクラスが与えられ、4 つ目のクラスを作成することになっています。私のコードは 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

あなたの問題は、不適切に初期化された配列が原因です!

WordCount[] searchWords;

しかし、あなたは決して宣言しませんsearchWords = new WordCount[dimension];

この配列を参照しようとすると、存在しないものにアクセスしようとしています。WordCount[]はそれ自体のオブジェクトであるため、まだオブジェクトを参照していないため、 をスローしてNullPointerExceptionWordCount[]ます。

于 2013-04-11T23:54:49.423 に答える
1

WordCount[] searchWords;配列が初期化されることはありません。

searchWords = new WorkCount[searchWorkdsAsStrings.length];アンダー追加searchWordsAsStrings = w.split(" ");

編集

以下のコメントから質問に答えるには、st.nextToken() がトークンを進めます。これが NoSuchElementException をスローしているものです。for ループ内でそれを行う代わりに、st.nextToken() を変数に読み込んでから、== 比較を行います。

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 に答える