【问题标题】:Getting NoSuchElementException获取 NoSuchElementException
【发布时间】:2015-12-30 10:09:52
【问题描述】:

我必须使用三个文本文件制作报告。所以我想到了将文件数据存储在数组中。这是我正在使用的文本文件。

    UnitID    UName  RNo     RName      Lect   RCapacity    StuEnrolled
    ECSC410;  SDP01; 21;    BreakRoom;  Dr.Fo;   6;             4;
    ECSI707;  SDP02; 23;    BreakRoom;  Dr.Fu;   8;             3;

这是我的代码。我得到NoSuchElementException。我不明白为什么会这样。请帮我解决它。

public static ArrayList<String> getRecords() {
    ArrayList<String> records = new ArrayList<>();

    BufferedReader br;
    try {
        br = new BufferedReader(new FileReader("G:\\lecturer.txt"));
        String line = br.readLine();

        while ( line != null){
            line = br.readLine();
            records.add(line);

        }
    } catch (FileNotFoundException ex) {
        Logger.getLogger(Lecture.class.getName()).log(Level.SEVERE, null, ex);
    } catch (IOException ex) {
        Logger.getLogger(Lecture.class.getName()).log(Level.SEVERE, null, ex);
    }
    return records;

}

public static ArrayList<Lecture> getLectureDetails(){
    ArrayList<Lecture> lectureDetails = new ArrayList<>();



    for (String record : getRecords()){
        StringTokenizer token = new StringTokenizer(record, ";");
        Lecture lecture = new Lecture();

        while(token.hasMoreTokens()){
            lecture.setUnitID(token.nextToken().trim());
            lecture.setUnitName(token.nextToken().trim());
            lecture.setRoomNo(token.nextToken().trim());
            lecture.setRoomName(token.nextToken().trim());
            lecture.setLecturerName(token.nextToken().trim());
            lecture.setRoomCapacity(Integer.parseInt(token.nextToken().trim()));
            lecture.setNoOfStudentsEnrolled(Integer.parseInt(token.nextToken().trim()));

            lectureDetails.add(lecture);
        }
    }
    return lectureDetails;

} 

谢谢!

【问题讨论】:

  • 您的文本文件中的某些行不能具有相同的列数!
  • 第一行没有所有列
  • 您的文本文件中是否有仅包含空格的行?可能是最后一行?

标签: java stringtokenizer nosuchelementexception


【解决方案1】:

您的问题在于缓冲阅读器的 while 循环。您正在检查上一个值是否为空,而不是检查下一个!如果 line 不为空,则它满足您的条件,但是您将获得下一行并使用它。重新安排你的逻辑:

        br = new BufferedReader(new FileReader("G:\\lecturer.txt"));
        String line = null;

        while ( (line=br.readLine()) != null){
            records.add(line);
        }

更新: 如果您这样做是为了跳过标题作为下面提到的评论者,那么您仍然可以保留最初的 readLine:

        br = new BufferedReader(new FileReader("G:\\lecturer.txt"));
        String line = br.readLine();

        while ( (line=br.readLine()) != null){
            records.add(line);
        }

附注:

StringTokenizer 是一个遗留类,不推荐使用。相反,您应该在字符串上使用 split 方法:

    for (String record : records) {

        String[] tokens = record.split(";");

        lecture.setUnitID(tokens[0].trim());
        lecture.setUnitName(tokens[1].trim());
        ...
    }

【讨论】:

  • 我认为他这样做是为了跳过标题
  • @name_no 他可能会这样做,但这意味着他正在阅读非行内容下的行,因此返回 null。
  • @name_no 感谢您指出这一点,我已经更新了问题以提供帮助!
  • @MasNotsram 谢谢!有用。即使是附加信息也非常有用,因为我是 Java 新手。 :)
【解决方案2】:

那是因为你在每一行都嵌入了逻辑错误和换行符。

首先,您使用StringTokenizer 标记数据的第一行,然后使用hasMoreTokens() 检查它是否有任何标记,然后将其中的所有标记提取到您的Lecture 对象中。你认为然后你得到下一行,但没有。

然后while 循环使用hasMoreTokens 再次检查您的第一个数据行,它仍然有最后一个标记,即换行符。所以循环进入第二次运行,但这次数据只有一个标记,你会得到错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多