在循环外使用scanner.next()会产生奇怪的结果

时间:2018-11-20 11:00:05

标签: java loops

最近,我的一个朋友向我展示了她的代码,以征询我的建议,以了解为什么它不起作用。她的原始代码是这样的:

public static void printStem(String word) ...

public static void main(String[] args)
{

  Scanner keyboard = new Scanner(System.in);
  System.out.println("Please enter the words: "); 
  String word = keyboard.next(); 
  printStem(word);

  while (keyboard.hasNext())
  {
    printStem(word);
    word = keybord.next();
  }
}

这将产生真正的奇怪结果。它将询问用户两次,然后执行两次printStem(这可能是预期的),然后继续执行操作,并始终打印 only 第一个输入的语料(单词)。

最终我发现,像这样从循环外部删除keyboard.next()时,它可以按预期工作

public static void printStem(String word) ...

public static void main(String[] args)
{
  Scanner keyboard = new Scanner(System.in);
  System.out.println("Please enter the words: "); 

  while (keyboard.hasNext())
  {
    String word = keybord.next();
    printStem(word);
  }
}

当被问到为什么会这样时,我没有合理的解释,因为这应该表现相同。我最好的猜测是hasNext()一定有异味,但我想不出为什么。所以。这里发生了什么?任何解释表示赞赏:)

2 个答案:

答案 0 :(得分:2)

有关hasNext()的一些解释:

Returns true if this scanner has another token in its input. 
This method may block while waiting for input to scan. 
The scanner does not advance past any input.

在您的第一段代码中

  
      
  1. 您扫描单词:String word = keyboard.next();

  2.   
  3. 您将其打印:printStem(word);

  4.   
  5. 您进入一个while循环,等待直到您输入以下内容:keyboard.hasNext()

  6.   
  7. 在第3步中,您将接受输入,但切勿将其存储在String word中并进行打印。自然会打印出单词的先前值。

  8.   
  9. 然后通过next()进行下一个读取。

  10.   

next()的解释:

Finds and returns the next complete token from this scanner. A complete token is preceded and followed by input that matches the delimiter pattern. This method may block while waiting for input to scan, even if a previous invocation of hasNext() returned true.

因此,您会有奇怪的行为。

答案 1 :(得分:0)

  

这将产生非常奇怪的结果

是的,因为逻辑是错误的。

您得到输入

String word = keyboard.next(); 

打印

printStem(word);

然后再次打印,并要求另一个单词:

while (keyboard.hasNext())
{
    printStem(word);
    word = keybord.next();
}

因此,每次循环时,都打印他们上次输入 的单词,而不是他们这次输入 的单词。您只需要在while循环中交换两行,然后使循环体内的keyboard.next()printStem(word)变得多余。

  

因为这应该表现相同

不,不应该。您反转了while循环主体中的操作顺序。