Java 获得无接触异常
我正在尝试做一个应用程序,应该有助于使地下城和龙的项目更容易为用户 我有3个不同武器的列表,具有不同的统计数据等。其中2个列表添加到程序中很好,但其中1个抛出NoSuchElementException。我真的不明白为什么,因为我找不到与我得到的其他列表有什么不同的地方 列表中的一行如下所示:Java 获得无接触异常,java,file-io,bufferedreader,Java,File Io,Bufferedreader,我正在尝试做一个应用程序,应该有助于使地下城和龙的项目更容易为用户 我有3个不同武器的列表,具有不同的统计数据等。其中2个列表添加到程序中很好,但其中1个抛出NoSuchElementException。我真的不明白为什么,因为我找不到与我得到的其他列表有什么不同的地方 列表中的一行如下所示: Light Melee Weapon,1d4,1d6,x2,10 ft.,Slashing,Axe (Throwing),8 gp, 2lb. 如果要查看,请链接到导致问题的整个列表 还可以链接到一个
Light Melee Weapon,1d4,1d6,x2,10 ft.,Slashing,Axe (Throwing),8 gp, 2lb.
如果要查看,请链接到导致问题的整个列表
还可以链接到一个工作正常的列表
我希望这个方法对你来说不会太长。我真的做了我能想到的一切来尝试解决这个问题。我敢肯定是列表导致了问题,因为只要我从它读取的目标中删除它,程序就会正常运行
它在工作的列表上可以很好地通过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;
}
线程“main”java.util.NoSuchElementException中的异常
位于java.util.StringTokenizer.nextToken(StringTokenizer.java:349)
位于MainGUI.init(MainGUI.java:60)
MainGUI.main(MainGUI.java:32)
公共HashMap init(){
字符串path=“base”;
文件夹=新文件(路径);
File[]listOfFiles=folder.listFiles();
if(listOfFiles.length==0){
JOptionPane.showMessageDialog(MainGUI.this,“文件夹\“base\”为空”+
“所以没有人试图装填武器或盔甲。”,“警告”,
JOptionPane。警告消息);
返回新的HashMap();
}
HashMap武器=新的HashMap();
BufferedReader r=null;
对于(文件f:listOfFiles){
if(f.getName().endsWith(“.txt”)){
弦线;
试一试{
r=新的BufferedReader(新的文件读取器(f));
而((line=r.readLine())!=null){
武器w;
StringTokenizer st=新的StringTokenizer(行,“,”);
而(st.hasMoreTokens()){
w=新武器(武器类别.fromString(st.nextToken()),
st.nextToken(),st.nextToken(),st.nextToken(),
st.nextToken(),st.nextToken(),st.nextToken(),
圣奈克特肯(),圣奈克特肯());
put(w.getName(),w);
}
}
}捕获(FileNotFoundException fnfe){
showMessageDialog(MainGUI.this,“文件”+
f、 找不到getName()+,“错误”,
JOptionPane.ERROR\u消息);
}捕获(ioe异常ioe){
showMessageDialog(MainGUI.this)“读取时出现问题”+
f、 getName()+“,”错误“,
JOptionPane.ERROR\u消息);
}
}
}
试一试{
r、 close();
}捕获(IOEX异常){
JOptionPane.showMessageDialog(MainGUI.this)表示,“在运行时发生错误”
+“正在关闭文件读取器流:\n”+ex.getMessage(),
“错误”,作业窗格。错误消息);
}
归还武器;
}
像这样编码
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()
标记行。它返回一个字符串[]
,您可以在尝试访问其元素之前轻松检查其大小。Stringtokenizer现在有点老派
如果您确定不会有包含逗号的条目,则可以使用Scanner或只使用逗号拆分
如果使用split,则可以检查零件中的条目数量是否包含正确数量的元素:
String[] parts = line.split(",")
if (parts.length != 9){
throw new RuntimeException("Bad line : " + line);
}
...
//continue processing
您还可以在每一行上增加一个计数器,然后显示导致异常的行 如果输入耗尽,则由于某些原因而发生NoTouchElementException,这在标准输入中不太可能发生(它将被阻塞)。不正确的值将产生InputMismatchException 如果没有任何数据类型检查,那么不用担心。但如果您想拥有不同的数据类型,那么应该在添加到bean对象之前进行检查。简单地尝试一下
String splitString = "Hi! Amazing! wonderful!"
for (String token : splitString.split("!")) {
System.out.println(token.toString());
}
- 结果:
Hi! Amazing! wonderful!