我正在尝试创建一个应用程序,以帮助用户更轻松地制作Dungeon和Dragons项目!
我有3个不同武器的列表,具有不同的统计数据等。其中2个列表被添加到程序中,但其中1个会抛出NoSuchElementException。我真的不明白为什么,因为我找不到与该列表有很大不同的东西,与其他列表相比。
列表中的一行如下所示:
Light Melee Weapon,1d4,1d6,x2,10 ft.,Slashing,Axe (Throwing),8 gp, 2lb.
http://pastebin.com/Fb2db0f1链接到整个列表会导致问题,如果你想看看。
http://pastebin.com/9Hg0Rw2a也链接到一个工作得很好的列表!
我希望这个方法不会太长,你无法查看。我已经做了所有我能想到的尝试来解决这个问题。而且我很肯定这是导致问题的列表,因为只要我从它读取的目的地删除它,程序运行就好了!
它在有效的列表上运行for循环,但第一个列表不起作用._。
Exception in thread "main" java.util.NoSuchElementException
at java.util.StringTokenizer.nextToken(StringTokenizer.java:349)
at MainGUI.init(MainGUI.java:60)
at MainGUI.main(MainGUI.java:32)
public HashMap<String,Weapon> init() {
String path = "base";
File folder = new File(path);
File[] listOfFiles = folder.listFiles();
if(listOfFiles.length == 0) {
JOptionPane.showMessageDialog(MainGUI.this, "The folder \"base\" was empty"+
" so no weapons or armor was attempted loaded.", "Warning",
JOptionPane.WARNING_MESSAGE);
return new HashMap<>();
}
HashMap<String, Weapon> weapons = new HashMap<>();
BufferedReader r = null;
for(File f : listOfFiles) {
if(f.getName().endsWith(".txt")) {
String line;
try {
r = new BufferedReader(new FileReader(f));
while((line = r.readLine()) != null) {
Weapon w;
StringTokenizer st = new StringTokenizer(line,",");
while(st.hasMoreTokens()) {
w = new Weapon(WeaponCategory.fromString(st.nextToken()),
st.nextToken(),st.nextToken(),st.nextToken(),
st.nextToken(),st.nextToken(),st.nextToken(),
st.nextToken(),st.nextToken());
weapons.put(w.getName(), w);
}
}
} catch(FileNotFoundException fnfe) {
JOptionPane.showMessageDialog(MainGUI.this, "The File "+
f.getName() + " was not found.", "Error",
JOptionPane.ERROR_MESSAGE);
} catch(IOException ioe) {
JOptionPane.showMessageDialog(MainGUI.this, "There was a problem reading "+
f.getName() + ".", "Error",
JOptionPane.ERROR_MESSAGE);
}
}
}
try {
r.close();
} catch (IOException ex) {
JOptionPane.showMessageDialog(MainGUI.this, "An error occured while"
+ "closing the File Reader Stream:\n"+ex.getMessage(),
"Error", JOptionPane.ERROR_MESSAGE);
}
return weapons;
}
答案 0 :(得分:0)
像这样的代码
while(st.hasMoreTokens()) {
w = new Weapon(WeaponCategory.fromString(st.nextToken()),
st.nextToken(),st.nextToken(),st.nextToken(),
st.nextToken(),st.nextToken(),st.nextToken(),
st.nextToken(),st.nextToken());
weapons.put(w.getName(), w);
}
是不安全的,因为您假设每个输入行中有9个项目。您应该检查项目数量并优雅地处理无效行(例如,通过写出行的内容以便更容易识别问题)。
实现此目的的一种简单方法是使用String.split()
来标记该行。它返回String[]
,您可以在尝试访问其元素之前轻松检查其大小。
答案 1 :(得分:0)
Stringtokenizer现在有点老了。
如果您确定不会包含逗号,则可以使用扫描程序或只使用逗号分割。
如果您选择拆分,您可以检查部件中的条目数量是否包含正确数量的元素:
String[] parts = line.split(",")
if (parts.length != 9){
throw new RuntimeException("Bad line : " + line);
}
...
//continue processing
您还可以在每一行上增加一个计数器,然后您可以显示哪一行导致异常。
答案 2 :(得分:0)
NoSuchElementException由于某些输入已用尽而发生,这在标准输入中不太可能发生(它会阻塞)。不正确的值将产生InputMismatchException。
如果没有任何数据类型检查,请不要担心。但是如果你想拥有不同的数据类型,那么在添加到bean对象之前应该检查。
答案 3 :(得分:0)
尝试简单......
String splitString = "Hi! Amazing! wonderful!"
for (String token : splitString.split("!")) {
System.out.println(token.toString());
}
<强>结果:强>
Hi!
Amazing!
wonderful!