2

According to the Java Documentation for util.Scanner.hasNextInt():

Returns true if there is another line in the input of this scanner. This method may block while waiting for input. The scanner does not advance past any input.

When using hasNextInt(), there is a possibility that it will cause the scanner to wait for an input from the user.

For example:

System.out.println("Enter something:");
while(!scn.hasNextInt()){
    //do whatever..
}

Output:

Enter something:_     //(The underscore indicates the prompt waiting for user input)

My question is: When will hasNextInt() wait for an input and when will it not? Is it when there are no tokens to receive in the i/o buffer, then it will wait for an input?

Note: I am not asking how to implement proper codes with .hasNextInt(). I am asking when will hasNextInt() wait for an input.

RealSkeptic
  • 33,993
  • 7
  • 53
  • 79
user3437460
  • 17,253
  • 15
  • 58
  • 106
  • @Elliott Frisch The question title may appear to be related to what I ask, but If you look at all the solutions in the post marked by you, you will see that the solutions is not related. I am asking a question on reading buffer from console. Further more the person who wrote the accepted solution himself isn't assured of his own answer. Lastly, I am asking about hasNextInt(), not hasNext(). Above all, there is no satisfactory solution in the post explaining when it blocks and when it doesn't. – user3437460 May 10 '16 at 11:02
  • it checks the buffer first - if it does not hold next token in full it will block and read more data... it's all in that one class and well documented. The answer to your question is as follows: It wait's for an input when the buffer does not hold next token in full. http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b27/java/util/Scanner.java#Scanner.hasNext%28java.util.regex.Pattern%29 – Palcente May 10 '16 at 11:35
  • Hmm, why is this question down voted? Perhaps the down voter can explain so I can improve my question next time? – user3437460 May 10 '16 at 17:10

1 Answers1

1

First, you should note that hasNextInt() actually does two tasks.

  1. Checks whether there is another token in the underlying stream.
  2. When there is one, it checks whether that token is in fact a valid int.

So the first thing it tries to do is get a complete token, based on the Scanner's delimiter. It checks if the data collected so far in memory is a complete token - that is, we have hit a delimiter or the end of the stream - and if so, it can move on to matching and deciding whether it is an int.

Suppose so far it had "12" in the input. You don't know if it's going to be 12, 123, 12.5, 12A etc. until you hit the delimiter or the end of the stream.

Now, if it can't find the delimiter, it tries to read more data from the underlying stream. When it does so, it can block. The block can be for a short time (when the underlying stream is a file, it may block momentarily until a block is fetched from disk), slightly longer (waiting for a packet to arrive from a network connection), or very long - in case the underlying stream is a console.

Input streams that come from console do not retrieve data until the user presses Return. So if the user typed something like 123 dog cat - but did not press Return, the underlying stream won't return from read(), and hasNextInt() will block until the user presses Return.

Once the user presses return, you actually have three tokens available, so the current hasNextInt() will return true, and then you'll be able to read that token and call hasNextInt() again, and it will not block, but rather return false immediately (there is a token, but it is not an integer). The same will be true for the next one, and then it will block again, as the user needs to input another line and press Return again.

So to sum up:

  • hasNextInt() will block whenever the underlying stream blocks.
  • When the underlying stream is a file or network, blocks are usually very short.
  • When the underlying stream is from a console, it will block for long periods when the previous line has already been scanned, but the user has not pressed Return to send the next line.
  • If there is more than one token on a single line when scanning from console, then it will block once for the first token on that line, and not block for the others.
RealSkeptic
  • 33,993
  • 7
  • 53
  • 79
  • Thanks for your effort writing this post. So basically, if there are no returnable tokens from the underlying stream, it will block until user hits the return key. (when scanner is reading from console). Am I right? – user3437460 May 10 '16 at 17:09