Java:我一辈子都弄不明白为什么我会在这里遇到 NullPointerException
Java: I can't for the life of me figure out why I'm getting a NullPointerException here
我正在创建一个基于控制台的 Evil Hangman 程序。不是在游戏开始时选择单词,而是通过选择包含用户输入的字母的单词来逐步缩小单词列表。
这是一个很常见的作业,所以我相信您以前听说过类似的作业。
这是规范,以备不时之需。
编译需要的文件和客户端:
在这个特定的 class 中有问题的方法是 record() 方法,这是迄今为止在这个作业中最难编程的方法。
我观察到两个主要问题:
a) 有以下 NullPointerException,我无法找出原因。它发生在一个单词被添加到列表的行中。据我所知,单词和列表应该都存在并且都已初始化。这不是列表不包含单词或列表未正确初始化的问题。它似乎只在第二次用户输入后发生。
Exception in thread "main" java.lang.NullPointerException
at HangmanManager.record(HangmanManager.java:66)
at HangmanMain.playGame(HangmanMain.java:59)
at HangmanMain.main(HangmanMain.java:39)
b) NullPointerException 可能是我之前尝试解决另一个问题时引起的。在 NullPointerException 发生之前,我在确定为什么程序选择的单词不符合预期输出时遇到了问题。无论我做什么,程序在遍历结束时选择的单词总是 "aa." 即使我故意选择 'a' 作为猜测,这应该有效地过滤掉 "aa"作为一个选择,它仍然出现了。
这是我目前的程序。
import java.util.*;
public class HangmanManager {
private String pattern;
private int length;
private int max;
private SortedSet<Character> guessesMade;
private Set<String> words;
private Set<String> currentWords;
private Map<String, Set<String>> patternMap;
public HangmanManager(List<String> dictionary, int length, int max){
if (length < 1 || max < 0){
throw new IllegalArgumentException();
}
this.length = length;
this.max = max;
words = new TreeSet<String>();
for (String word : dictionary){
if (word.length() == length){
words.add(word);
}
}
currentWords = new TreeSet<String>();
guessesMade = new TreeSet<Character>();
patternMap = new TreeMap<String, Set<String>>();
pattern = "";
for (int i = 0; i < length; i++){
pattern += "- ";
}
}
public Set<String> words(){
return words;
}
public int guessesLeft(){
return max - guessesMade.size();
}
public SortedSet<Character> guesses(){
return guessesMade;
}
public String pattern(){
if (words.isEmpty()){
throw new IllegalArgumentException("There are no words.");
}
return pattern;
}
public int record(char guess){
if (guessesLeft() < 1 || words.isEmpty()){
throw new IllegalStateException();
}
if (!words.isEmpty() && guessesMade.contains(guess)) {
throw new IllegalArgumentException();
}
guessesMade.add(guess);
int largestOccurences = 0;
for (String word: words){
System.out.println(word);
System.out.println(words.size());
if (patternMap.containsKey(pattern)){
System.out.println("patternMap contains pattern");
largestOccurences = generatePattern(word, guess);
currentWords.add(word);
currentWords = patternMap.get(pattern);
patternMap.put(pattern, currentWords);
} else {
currentWords.add(word);
patternMap.put(pattern, currentWords);
}
}
words = findFamily();
return largestOccurences;
}
private Set<String> findFamily(){
int maxSize = 0;
Map <String, Integer> patternCount = new TreeMap<String, Integer>();
for (String key : patternMap.keySet()){
patternCount.put(key, patternMap.get(key).size());
if (patternMap.get(key).size() > maxSize){
maxSize = patternMap.get(key).size();
pattern = key;
} else if (patternMap.get(key).size() == maxSize){
if (key.length() >= pattern.length()){
pattern = key;
maxSize = patternMap.get(key).size();
}
}
}
System.out.println("Current pattern: " + pattern);
return patternMap.get(pattern);
}
private int generatePattern(String s, char guess) {
int count = 0;
pattern = "";
for (int i = 0; i < length; i++){
if (s.charAt(i) == guess){
pattern += guess + " ";
count++;
} else {
pattern += "- ";
}
}
return count;
}
}
你的问题是patternMap
。
if (patternMap.containsKey(pattern))
{
System.out.println("patternMap contains pattern");
largestOccurences = generatePattern(word, guess);
//=> generatePattern changes the global variable pattern, so it may
//not be contained in patternMap anymore
currentWords.add(word);
currentWords = patternMap.get(pattern);//since pattern was changed,
//patternMap return null and
//you get NullPointerException on
//the next iteration of the loop
patternMap.put(pattern, currentWords);
}
您需要确保在调用 currentWords = patternMap.get(pattern);
时新更改的 pattern
存在于 patternMap
中。否则,你会得到 null
.
赋值前检查是否为空..
currentWords = patternMap.get(模式);
将其替换为
如果(patternMap.get(模式)!=空)
currentWords = patternMap.get(模式);
检查一下...如果您有任何此类分配,请进行空检查..
祝你好运!
我正在创建一个基于控制台的 Evil Hangman 程序。不是在游戏开始时选择单词,而是通过选择包含用户输入的字母的单词来逐步缩小单词列表。
这是一个很常见的作业,所以我相信您以前听说过类似的作业。
这是规范,以备不时之需。
编译需要的文件和客户端:
在这个特定的 class 中有问题的方法是 record() 方法,这是迄今为止在这个作业中最难编程的方法。 我观察到两个主要问题:
a) 有以下 NullPointerException,我无法找出原因。它发生在一个单词被添加到列表的行中。据我所知,单词和列表应该都存在并且都已初始化。这不是列表不包含单词或列表未正确初始化的问题。它似乎只在第二次用户输入后发生。
Exception in thread "main" java.lang.NullPointerException
at HangmanManager.record(HangmanManager.java:66)
at HangmanMain.playGame(HangmanMain.java:59)
at HangmanMain.main(HangmanMain.java:39)
b) NullPointerException 可能是我之前尝试解决另一个问题时引起的。在 NullPointerException 发生之前,我在确定为什么程序选择的单词不符合预期输出时遇到了问题。无论我做什么,程序在遍历结束时选择的单词总是 "aa." 即使我故意选择 'a' 作为猜测,这应该有效地过滤掉 "aa"作为一个选择,它仍然出现了。
这是我目前的程序。
import java.util.*;
public class HangmanManager {
private String pattern;
private int length;
private int max;
private SortedSet<Character> guessesMade;
private Set<String> words;
private Set<String> currentWords;
private Map<String, Set<String>> patternMap;
public HangmanManager(List<String> dictionary, int length, int max){
if (length < 1 || max < 0){
throw new IllegalArgumentException();
}
this.length = length;
this.max = max;
words = new TreeSet<String>();
for (String word : dictionary){
if (word.length() == length){
words.add(word);
}
}
currentWords = new TreeSet<String>();
guessesMade = new TreeSet<Character>();
patternMap = new TreeMap<String, Set<String>>();
pattern = "";
for (int i = 0; i < length; i++){
pattern += "- ";
}
}
public Set<String> words(){
return words;
}
public int guessesLeft(){
return max - guessesMade.size();
}
public SortedSet<Character> guesses(){
return guessesMade;
}
public String pattern(){
if (words.isEmpty()){
throw new IllegalArgumentException("There are no words.");
}
return pattern;
}
public int record(char guess){
if (guessesLeft() < 1 || words.isEmpty()){
throw new IllegalStateException();
}
if (!words.isEmpty() && guessesMade.contains(guess)) {
throw new IllegalArgumentException();
}
guessesMade.add(guess);
int largestOccurences = 0;
for (String word: words){
System.out.println(word);
System.out.println(words.size());
if (patternMap.containsKey(pattern)){
System.out.println("patternMap contains pattern");
largestOccurences = generatePattern(word, guess);
currentWords.add(word);
currentWords = patternMap.get(pattern);
patternMap.put(pattern, currentWords);
} else {
currentWords.add(word);
patternMap.put(pattern, currentWords);
}
}
words = findFamily();
return largestOccurences;
}
private Set<String> findFamily(){
int maxSize = 0;
Map <String, Integer> patternCount = new TreeMap<String, Integer>();
for (String key : patternMap.keySet()){
patternCount.put(key, patternMap.get(key).size());
if (patternMap.get(key).size() > maxSize){
maxSize = patternMap.get(key).size();
pattern = key;
} else if (patternMap.get(key).size() == maxSize){
if (key.length() >= pattern.length()){
pattern = key;
maxSize = patternMap.get(key).size();
}
}
}
System.out.println("Current pattern: " + pattern);
return patternMap.get(pattern);
}
private int generatePattern(String s, char guess) {
int count = 0;
pattern = "";
for (int i = 0; i < length; i++){
if (s.charAt(i) == guess){
pattern += guess + " ";
count++;
} else {
pattern += "- ";
}
}
return count;
}
}
你的问题是patternMap
。
if (patternMap.containsKey(pattern))
{
System.out.println("patternMap contains pattern");
largestOccurences = generatePattern(word, guess);
//=> generatePattern changes the global variable pattern, so it may
//not be contained in patternMap anymore
currentWords.add(word);
currentWords = patternMap.get(pattern);//since pattern was changed,
//patternMap return null and
//you get NullPointerException on
//the next iteration of the loop
patternMap.put(pattern, currentWords);
}
您需要确保在调用 currentWords = patternMap.get(pattern);
时新更改的 pattern
存在于 patternMap
中。否则,你会得到 null
.
赋值前检查是否为空.. currentWords = patternMap.get(模式);
将其替换为 如果(patternMap.get(模式)!=空) currentWords = patternMap.get(模式);
检查一下...如果您有任何此类分配,请进行空检查..
祝你好运!