LinkedHashMap и NullPointerException
Я работал над созданием генератора имен на основе цепей Маркова. Пока что код может найти вероятность следующей буквы и поместить ее в LinkedHashMap
(Который я буду называть LHM после этой точки) по имени states
используя generateProbabilities()
функция. LHM хранит данные так, что первый ключ - это состояние, а второй - буква перехода.
Тем не менее, здесь все становится интересным. У меня есть три выходных оператора, один в generate()
функция, и два в WeightedRandom
в этом. Вот мой вывод:
РЕДАКЦИОННЫЙ РАЗДЕЛ:
Called from generate(): [0.13333333333333333, 0.13333333333333333, 0.13333333333333333, 0.06666666666666667, 0.13333333333333333, 0.06666666666666667, 0.06666666666666667, 0.13333333333333333, 0.06666666666666667, 0.06666666666666667]
Called from WeightedRandom (Size): 10
Called from WeightedRandom (Values): [0.13333333333333333, 0.13333333333333333, 0.13333333333333333, 0.06666666666666667, 0.13333333333333333, 0.06666666666666667, 0.06666666666666667, 0.13333333333333333, 0.06666666666666667, 0.06666666666666667]
Exception in thread "main" java.lang.NullPointerException
at WeightedRandom.<init>(WeightedRandom.java:14)
at MarkovChain.generate(MarkovChain.java:102)
at Temp.main(Temp.java:7)
Странная часть в том, что NPE в строке 14 является вторым оператором println в WeightedRandom
и он был брошен после того, как распечатал данные. Третий println печатает без ошибок. Так что я не забыл инициализировать его или у меня не было правильного ключа для получения NPE. Код ниже:
MarkovChain.java
public class MarkovChain {
public String filePath;
public LinkedHashMap<String,LinkedHashMap<String,Double>> states = new LinkedHashMap<String,LinkedHashMap<String,Double>>();
public MarkovChain(String filePath){
this.filePath = filePath;
}
public void generateProbabilities(String delimiter){
//Creates a hashmap of probabilities for each letter.
}
public String generate(int iterations){
Random rand = new Random();
LinkedHashMap<String,Double> currProbabilities = states.get("a"); // Placeholder for random start state;
String output = "";
WeightedRandom weightRand;
System.out.println("Called from generate(): " + currProbabilities.values());
for(int i = 0; i<iterations; i++){
weightRand = new WeightedRandom(currProbabilities);
String newState = weightRand.compute();
output+=newState;
currProbabilities = states.get(newState);
}
return output;
}
}
WeightedRandom.java
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import java.util.Set;
public class WeightedRandom {
LinkedHashMap<String,Double> items;
Random rand = new Random();
public WeightedRandom(LinkedHashMap<String,Double> items){ //Currently Single-Purpose.
this.items = items;
System.out.println("Called from WeightedRandom (Size): " + items.size());
System.out.println("Called from WeightedRandom (Values): " + items.values());
}
public String compute(){
items.values();
/*
Set s = items.entrySet();
Iterator i = s.iterator();
double randNum = rand.nextDouble();
double runningTotal = 0;
String output = null;
while(i.hasNext() && output == null){
Map.Entry entry = (Map.Entry)i.next();
if(randNum < runningTotal + (double)entry.getValue() && randNum > runningTotal){
output = (String)entry.getKey();
}
}
return output;
*/
return null;
}
}