0

I have perused numerous other solutions to NPEs, and I've tried to implement other suggestions, but none of them quite match up what I'm trying to do and it just leads to more eclipse errors. I have compiled and tried to run from the command line, giving the application I'm running a couple strings when running at the command line. Below is the main class, and the class containing the methods that the main is using.

Class with the main method:

package my.package.ext;



public class WordCounterApp {

    /**
     * @param args
     * Two command line arguments: the first one needs to be in quotes, the string that will be used, the second optional argument
     * is the unique word to be counted (countWord method).
     * @param source 
     * @param word 
     */
    public static void main(String[] args) {
        String source = null;
        String uniqueword = null;
        StringBuilder word = null;
        WordCounter counter = new WordCounter(source, word);
        WordCounter uniqueCounter = new WordCounter(source, uniqueword);
        counter.countWords(source);
        counter.countUniqueWords(source);
        uniqueCounter.countWord(source, uniqueword);

}

}

Class with the other methods:

package my.package.ext;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.lang.Character;
import java.lang.StringBuilder;

public class WordCounter {
    public Integer counter = 0;
    public String source;
    public HashSet<String> hashset;
    public StringBuilder word;
    public String uniqueword;

    public WordCounter(String source) {
         counter = new Integer(counter);
    }
    public WordCounter(String source, StringBuilder word) {
         counter = new Integer(counter);
    }
    public WordCounter(String source, String uniqueword) {
        counter = new Integer(counter);
    }
    /**
     *  
     * @param line - the string parameter to get a total word count from.
     */

    public int countWords(String source) {

        boolean word = false;
        int endOfLine = source.length() - 1;
        Integer counter = 0;

        for (int i = 0; i < source.length(); i++) {
            if (Character.isLetter(source.charAt(i)) == true && i != endOfLine) {
                word = true;
            //} else if (Character.charValue(line.charAt(i)) == "-" && i != endOfLine) {
            //  word = true;
            } else if (Character.isLetter(source.charAt(i)) == false && word == true) {
                counter++;
                word = false;
            } else if (Character.isLetter(source.charAt(i)) && i == endOfLine) {
                counter++;
            }
        }
        System.out.println(counter);
        return counter;
    }




/**
 * 
 * @param line - the string parameter that we will return the unique word count from. Randy recommends a HashSet.
 * Put it into a hashset. Hashsets don't allow duplicate elements. Then do a count. 
 */

    public int countUniqueWords(String line) {
        hashset = new HashSet<String>();
        word = new StringBuilder();
        int endOfLine = line.length() - 1;
        boolean isWord = false;
        String stringWord = null;
        Integer counter = 0;

        for (int i = 0; i < line.length(); i++) {
            if (Character.isLetter(line.charAt(i)) == true && i != endOfLine) {
                //System.out.println(i);
                word.append(line.charAt(i));
                isWord = true;
            } else if (Character.isLetter(line.charAt(i)) == false && isWord == true) {
                counter++;
                //System.out.println("Counter is: " + counter);
                stringWord = word.toString();
                //System.out.println("stringWord is now: " + stringWord);
                hashset.add(stringWord);
                //System.out.println(hashset);
                word = new StringBuilder();
                isWord = false;
            } else if (Character.isLetter(line.charAt(i)) && i == endOfLine) {
                counter++;
                stringWord = word.toString();
                hashset.add(stringWord);
            }
        }
        //System.out.println(counter);
        System.out.println("There are " + hashset.size() + " unique words in this string");
        System.out.println("These are the unique words in the string: " + hashset);
        return counter;

    }


/**
 * 
 * @param source - the string the word is to be counted from
 * @param word - the word to be counted
 * 
 */
    public void countWord(String source, String word) {

        String str = source;
        Pattern p = Pattern.compile("\\s"+word+"\\s");
        Matcher m = p.matcher(str);
        int count = 0;
        while (m.find()) {
            count++;
        }
        System.out.println("The word: " + "\"" + word + "\"" + " appears " + count + " times.");
        }

}

I have identified the source of the NPE here:

public int countWords(String source) {

    boolean word = false;
    int endOfLine = source.length() - 1;  //the source of the NPE is this line
    Integer counter = 0;

So looking at that, I figure I'm not initializing source correctly. I have tried things like WordCounter source = new WordCounter()

But every variant of this I try, bringing in the correct constructor, gives me other eclipse errors. I can't seem to get there, and I'm afraid I'm going down the wrong path. I probably have other screw ups in here as well. I'm also unsure of the correct way to run from the command line while passing in some strings as arguments to feed the methods. Thanks in advance

4

7 に答える 7

2

あなたsourceのメインメソッドのあなたの文字列は、nullそれを引数としてcountWordsメソッドに渡しています。

 public static void main(String[] args) {
        String source = null;// it is null here
        ..............
        ............
        counter.countWords(source);// passing null here

したがって、あなたが呼び出すときのcountWords

    int endOfLine = source.length() - 1;

ソースが null であるため、NullPointerException がスローされます。

文字列を初期化して NPE を取り除きます。

編集: source をコマンドライン引数として渡したい場合。

String source =args[0];

実行時にコマンドライン引数を渡します。

于 2012-11-05T23:31:02.887 に答える
0

あなたの主な方法:

public static void main(String[] args) {
        String source = null;
        // ... a few lines
        counter.countWords(source);
        // ... more code

}

結果のエラー:

public int countWords(String source) {
    boolean word = false;
    int endOfLine = source.length() - 1;  //the source of the NPE is this line
    Integer counter = 0;
}

起こるので御座いsourceますnull

于 2012-11-05T23:30:59.203 に答える
0

「手動行解析」アプローチに基づく私のバージョンは次のとおりです。

package forums;

import java.util.List;
import java.util.ArrayList;
import java.util.Set;
import java.util.HashSet;
import java.util.regex.Pattern;
import java.util.regex.Matcher;

public class WordCounterApp {

    private static void printUsage() {
        System.out.println("usage: java -cp C:\\Java\\home\\classes forums.WordCounterApp <text> [targetWord]");
        System.out.println("   <text> is a quoted string to be split into words.");
        System.out.println("   optional [targetWord] to be counted seperately.");
    }

    /**
     * @param args
     *  REQUIRED [0] text: a quoted string to be searched for words. 
     *  OPTIONAL [1] targetWord: the word to be counted, if desired.
     */
    public static void main(String[] args) {
        if (args.length==0) {
            printUsage();
            return;
        }
        String text = args[0];
        String targetWord = args.length>1 ? args[1] : null;
        WordCount wordCount = new WordCount(text);

        System.out.println();

        // all words in this string
        List<String> words = wordCount.all();
        System.out.println("There are "+words.size()+" words in the string. That are:\n"+words);
        System.out.println();

        // unique words in this string
        Set<String> uniqueWords = wordCount.unique();
        System.out.println("There are "+uniqueWords.size()+" unique words in the string. They are:\n"+uniqueWords);
        System.out.println();

        // the number of occurrences of the target word in this string, if given
        if (targetWord ! = null) {
            int targetCount = wordCount.of(targetWord);
            System.out.println("The word \""+targetWord+"\" appears "+targetCount+" times.");
            System.out.println();
        }

    }
}

/**
 * Counts the words on a line, in various ways.
 */
class WordCount 
{
    private final String _line;
    public WordCount(String line) {
        _line = line;
    }

    public List<String> all() {
        final List<String> results = new ArrayList<String>(64); // just a guess at max word-count.
        final Matcher matcher = Pattern.compile("\\w+").matcher(_line);
        int count = 0;
        while ( matcher.find() )
            results.add(matcher.group());
        return results;
    }

    /**
     * Returns a set of the unique words in the line
     */
    public Set<String> unique() {
        final HashSet<String> results = new HashSet<String>();
        final int lineLength = _line.length();
        final int endOfLine = lineLength-1;
        final StringBuilder wordBuffer = new StringBuilder(16); // just a guess at max-word-length
        char ch;
        boolean isInWord = false;
        // foreach character in the line EXCEPT the last one:
        for ( int i=0; i<endOfLine; ++i ) {
            ch = _line.charAt(i);
            if ( Character.isLetter(ch) ) {
                // we're at the start or continuation of the current word.
                wordBuffer.append(ch);
                isInWord = true;
            } else if ( isInWord ) {
                // we're reached the end-of-word, or the end-of-the-line.
                results.add(wordBuffer.toString());
                wordBuffer.setLength(0); // clear the word-buffer.
                isInWord = false;
            }
        }
        // handle the last character in the line seperately, just to save
        // testing for it everytime through the loop... and I personally 
        // think that the logic is easier to follow this way.
        ch = _line.charAt(endOfLine);
        if ( Character.isLetter(ch) )
            wordBuffer.append(ch);
        if ( wordBuffer.length() > 0 )
            results.add(wordBuffer.toString());
        return results;
    }

    /**
     * Returns the number of occurences of the targetWord.
     * @param targetWord - the word to be counted.
     */
    public int of(String targetWord) {
        final String regex = "\\s+"+targetWord+"\\s+";
        final Matcher matcher = Pattern.compile(regex).matcher(_line);
        int count = 0;
        while ( matcher.find() )
            ++count;
        return count;
    }

}

自分でこれを行っていた場合、allメソッドはString.split(String regex)を使用するだけです (より簡潔であるため); そして、uniqueメソッドは、行外の単語を「手動で解析」するのではなく、メソッドの結果から開始しますall(これもはるかに簡潔であるためです)。

また、これを実際に行っている場合は、 「頻度表」を含むメソッド、つまり、各単語の出現回数へのマップをfrequencyTable返す 1 つのメソッドを使用する傾向があります。HashMap<String, int>このレシピは柔軟 (したがって再利用可能) であり、より効率的である傾向があります。これは、通常、行を 1 回解析してから、解析結果を繰り返しクエリするためです...そして、結果を 1 回だけクエリする場合は、実際にはそうではありません。数クロックティックを除いて何も失いませんでしたが、最近では数十億になります。

于 2012-11-06T01:25:39.463 に答える
0

ソースとして null を渡し、少し後で source.length を呼び出します。それがNPEの原因です。

于 2012-11-05T23:31:25.083 に答える
0

counter.countWords(ソース);

ここで、ソース文字列が null であり、NPE が発生します。

于 2012-11-05T23:31:47.710 に答える
0

メイン メソッドでは、 be に割り当てsourceますnull。それを他のものに再割り当てすることは決してないので、呼び出すときcounter.countWords(source)は を呼び出すのと同じですcounter.countWords(null)

これは、countWords()を呼び出そうとする行に到達するとsource.length()source実際にはaがスローされるnull原因となっていることを意味します。NullPointerExceptionこれを回避するには、sourceそのメソッドを呼び出す前に何かを代入する必要があります。

于 2012-11-05T23:32:58.517 に答える
-1

シティ17モーグル、

argsメイン メソッドで読むのをやめました。すでに show-stopper を見つけたからです。 (メイン メソッドに渡されたコマンドライン引数)で何もしていないので、 sourceuniqueWord、およびword変数は ALLWAYSnullです。 ..そして、それがあなたの根本的な原因だと思いますNullPointerException

また、Google で検索することもできます: How to read a stacktrace... これは新しいプログラマーが学ばなければならないスキルであり、このスキルは (ほぼすべての) 現代の言語間でさえも移植可能です。

スタックトレースは、NPE が発生するコードの行を正確に示しており、そこから、通常、どの変数が null であるかをワークアウトするのは非常に簡単です...特にデバッガーを使用している場合...単にブレークポイントを配置するだけです問題のある行で、同じ入力でプログラムを再実行し、その行のすべての変数の値を調べます...それらの1つ以上がnullでなければなりません。

乾杯。キース。

于 2012-11-05T23:37:04.480 に答える