Java StringTokenizer“;“非接触性异常”;

Java StringTokenizer“;“非接触性异常”;,java,Java,所以出于某种原因,我得到了一个java.lang.Exception:java.util.NoSuchElementException。价值观是这样的 back bison 1.0 back dog 3.0 becaue bison 1.0 best bison 1.0 david bison 1.0 ever bison 1.0 i bison 1.0 i dog 4.0 im bison 1.0 is bison 1.0 但在最后,我得到了一个非接触式的例外: 我的代码很简单: Strin

所以出于某种原因,我得到了一个java.lang.Exception:java.util.NoSuchElementException。价值观是这样的

back
bison
1.0
back
dog
3.0
becaue
bison
1.0
best
bison
1.0
david
bison
1.0
ever
bison
1.0
i
bison
1.0
i
dog
4.0
im
bison
1.0
is
bison
1.0
但在最后,我得到了一个非接触式的例外:

我的代码很简单:

StringTokenizer line = new StringTokenizer(new String(value.getBytes()));
    while (line.hasMoreElements()){
        Text unWord = new Text((String) line.nextElement());
        String unAuth = (String) line.nextElement();
        float unVal = Float.parseFloat(line.nextToken());

        System.out.println(unWord);
        System.out.println(unAuth);
        System.out.println(unVal);
    }

我似乎不明白为什么元素会打印出来,但最后我会得到一个NoTouchElementException

您调用
line.nextElement()
两次,而只检查
line.hasMoreElements()
一次。是否最后只剩下一个元素,而不是两个?

问题是每次迭代调用一次
hasMoreElements()
,但调用
nextElement
/
nextToken
三次。这很容易出错。即使文件遵循确切的格式,例如在您的案例中,也有可能在末尾有一个空行

看起来这正是在您的案例中发生的情况:当您询问标记器是否有更多的元素时,您得到了
true
,但只有一个元素,恰好是新行字符。对
nextElement
的第一次调用成功,但第二次调用失败

要解决此问题,请添加
hasMoreElements()
在每次调用
nextElement
之前检查,如果没有下一个元素,请退出:

Text unWord = new Text((String) line.nextElement());
if (!line.hasMoreElements()) break;
String unAuth = (String) line.nextElement();
if (!line.hasMoreElements()) break;
float unVal = Float.parseFloat(line.nextToken());

在循环的每次迭代中,您测试一次是否有更多可用的令牌,然后尝试从令牌化器中提取三个令牌。如果三个令牌都成功绘制,则打印结果,但您只能确信其中一个令牌绘制成功。如果原始字符串中的令牌总数不是三的倍数,那么您肯定会得到一个
NoTouchElementException
。如果您认为您的数据在其他方面看起来与您预期的一样,那么这可能是由于原始字符串中的尾随空格(在末尾产生意外的空标记)。

谢谢。它接受了一个新的台词角色,并将其抛弃。