线程“main”java.util.NoSuchElementException中的异常

时间:2017-02-22 11:03:24

标签: java

我正在练习编写java代码,我尝试修复此问题,但我不知道如何修复它。我会告诉你我的代码。

在我的Fortunecookie.java中:

public class FortuneCookie {
    private String subjectList;
    private String objectList;
    private String verbList;
    private int sWord;
    private int oWord;
    private int vWord;
    private Random random = new Random() enter code here;

    public FortuneCookie() {
        subjectList = "I#You#He#She#It#They";
        objectList = "me#you#him#her#it#";
        verbList = "hate#love#deny#find#hear#forgive#hunt#win#teach";
    }

    public String getFortuneMsg() {
        StringTokenizer subSt = new StringTokenizer(subjectList,"#");
        StringTokenizer objSt = new StringTokenizer(objectList,"#");
        StringTokenizer verbSt = new StringTokenizer(verbList,"#");
        sWord = subSt.countTokens();
        oWord = objSt.countTokens();
        vWord = verbSt.countTokens();
        int c1 = random.nextInt(sWord);
        String line1 = " ";
        String line2 = " ";
        String line3 = " ";
        while(subSt.hasMoreTokens()) {
            line1 = subSt.nextToken("#");
            for (int i=0;i<sWord;i++)
                if (i == c1) {
                    break;
                }
                else{
                    line1 = subSt.nextToken("#");
                }
        }
        int c2 = random.nextInt(oWord);
        while(objSt.hasMoreTokens()) {
            line2 = objSt.nextToken("#");
            for (int i=0;i<sWord;i++)
                if (i == c2) {
                    break;
                }
                else{
                    line2 = objSt.nextToken("#");
                }
        }
        int c3 = random.nextInt(vWord);
        while(verbSt.hasMoreTokens()) {
            line3 = verbSt.nextToken("#");
            for (int i=0;i<sWord;i++)
                if (i == c3) {
                    break;
                }
                else{
                    line3 = verbSt.nextToken("#");
                }
        }
        return line1+line2+line3;
    }

    public void setSubjectList(String aSubjectList) {
        subjectList = aSubjectList;
    }

    public void setObjectList(String aObjectList) {
        objectList = aObjectList;
    }

    public void setVerbList(String aVerbList) {
        verbList = aVerbList;
    }

    public void print() {
        StringTokenizer subSt = new StringTokenizer(subjectList,"#");
        StringTokenizer objSt = new StringTokenizer(objectList,"#");
        StringTokenizer verbSt = new StringTokenizer(verbList,"#");
        sWord = subSt.countTokens();
        oWord = objSt.countTokens();
        vWord = verbSt.countTokens();
        System.out.println("Subject List : "+subjectList);
        System.out.println("Object List : "+objectList);
        System.out.println("Verb List : "+verbList);
    }

在我的FortuneCookieTest.java中

public class FortuneCookieTest {
    public static void main(String[] args) {
        FortuneCookie ck = new FortuneCookie();
        System.out.println(ck.getFortuneMsg());
    }
}

当我编译并运行它时:

//Exception in thread "main" java.util.NoSuchElementException
        at java.util.StringTokenizer.nextToken(Unknown Source)
        at java.util.StringTokenizer.nextToken(Unknown Source)
        at CS_111_Homework_2.FortuneCookie.getFortuneMsg(FortuneCookie.java:39)
        at CS_111_Homework_2.FortuneCookieTest.main(FortuneCookieTest.java:6)

我该如何解决?

2 个答案:

答案 0 :(得分:0)

在代码的这一部分中,您可以调用objSt.nextToken("#")两次,如果第一次调用获取最后一个元素,则在第二次调用时,您将获得NoSuchElementException,因为没有更多元素可用。

while (objSt.hasMoreTokens()) {
    line2 = objSt.nextToken("#");
    for (int i = 0; i < sWord; i++)
        if (i == c2) {
            break;
        } else {
            line2 = objSt.nextToken("#");
        }
}

This is a different use case, but has the same problem

答案 1 :(得分:0)

实际上代码有几个问题,特别是这个方法getFortuneMsg()

  1. 您正在对所有循环使用sWord,而您应该使用sWord作为第二个oWord和最后一个vWord的第一个循环line1 = subSt.nextToken("#");
  2. 此外,您在开始循环之前调用了NoSuchElementException,因此您已经使用了一个令牌,这可能会产生for (int i=0; i<sWord; i++)我建议将此for (int i=0; i<sWord - 1; i++)更改为此while(subSt.hasMoreTokens())考虑消耗的令牌。
  3. 对于此循环c1 < sWord,如果并非所有令牌都被消耗,它将重新开始(可能会在getFortuneMsg()时发生。)
  4. 注意:代码需要进行一些重构以防止重复并明智地使用循环。

    编辑:我并不完全明白你想要实现的目标,但如果我是你,我想将此方法 public String getFortuneMsg() { StringTokenizer[] tokenizers = {new StringTokenizer(subjectList, "#"), new StringTokenizer(objectList, "#"), new StringTokenizer(verbList, "#")}; StringBuilder sb = new StringBuilder(); for (StringTokenizer tokenizer : tokenizers) { int rCount = random.nextInt(tokenizer.countTokens()); for (int i = 0; i < rCount; i++) { tokenizer.nextToken(); } sb.append(tokenizer.nextToken()); } return sb.toString(); } 更改为以下内容:

    In [24]:
    df.loc[df['Name'] == 'ID stored']
    
    Out[24]:
       ID       Name  Test
    0   1  ID stored     0
    1   2  ID stored     0
    5   3  ID stored     2