我正在编写课程代码。我们的意思是扫描用户指定的文件中的行,在每行中搜索用户指定的一个或多个单词,并报告整个文件(逐行处理)存在这些单词的次数。我们给了三个班,并打算写第四个。我的代码在第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));
}
}
我确实无法追踪异常的来源。我已经阅读了生成它的内容(本网站上的许多解释),但我无法诊断实际代码中的异常是什么。
非常感谢。
答案 0 :(得分:6)
您的问题是因为阵列初始化不正确!
WordCount[] searchWords;
但你永远不会宣布searchWords = new WordCount[dimension];
当您尝试引用此数组时,您尝试访问不存在的内容。因为WordCount[]
本身就是一个对象,所以它会抛出一个NullPointerException
,因为它还没有引用WordCount[]
个对象。
答案 1 :(得分: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();
}
}
答案 2 :(得分:1)
在初始化之前,您似乎尝试将对象分配给searchWords数组(除非在超类中完成)。确保初始化数组,如
WordCount[] wordArray = new WordCount[10];
或
WordCount[] wordArray = new WordCount[]{new WordCount()};