Understanding Scanner's nextLine(), next(), and nextInt() methods
nextLine() reads the remainder of the current line even if it is empty.
Correct.
nextInt() reads an integer but does not read the escape sequence "\n".
Correct1.
next() reads the current line but does not read the "\n".
Incorrect. In fact, the next()
method reads the next complete token. That may or may not be the rest of the current line. And it may, or may not consume an end-of line, depending on where the end-of-line is. The precise behavior is described by the javadoc, and you probably need to read it carefully for yourself in order that you can fully understand the nuances.
So, in your example:
The nextInt() call consumes the
2
character and leaves the position at theNL
.The next() call skips the
NL
, consumesH
andi
, and leaves the cursor at the second NL.The nextLine() call consumes the rest of the 2nd line; i.e. the
NL
.
1 ... except that your terminology is wrong. When the data is being read, it is not an escape sequence. It is an end-of-line sequence that could consist of a CR, a NL or a CR NL depending on the platform. The escape sequences you are talking about are in Java source code, in string and character literals. They may >>represent<< a CR or NL or ... other characters.
What's the difference between next() and nextLine() methods from Scanner class?
I always prefer to read input using nextLine()
and then parse the string.
Using next()
will only return what comes before the delimiter (defaults to whitespace). nextLine()
automatically moves the scanner down after returning the current line.
A useful tool for parsing data from nextLine()
would be str.split("\\s+")
.
String data = scanner.nextLine();
String[] pieces = data.split("\\s+");
// Parse the pieces
For more information regarding the Scanner class or String class refer to the following links.
Scanner: http://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html
String: http://docs.oracle.com/javase/7/docs/api/java/lang/String.html
Scanner is skipping nextLine() after using next() or nextFoo()?
That's because the Scanner.nextInt
method does not read the newline character in your input created by hitting "Enter," and so the call to Scanner.nextLine
returns after reading that newline.
You will encounter the similar behaviour when you use Scanner.nextLine
after Scanner.next()
or any Scanner.nextFoo
method (except nextLine
itself).
Workaround:
Either put a
Scanner.nextLine
call after eachScanner.nextInt
orScanner.nextFoo
to consume rest of that line including newlineint option = input.nextInt();
input.nextLine(); // Consume newline left-over
String str1 = input.nextLine();Or, even better, read the input through
Scanner.nextLine
and convert your input to the proper format you need. For example, you may convert to an integer usingInteger.parseInt(String)
method.int option = 0;
try {
option = Integer.parseInt(input.nextLine());
} catch (NumberFormatException e) {
e.printStackTrace();
}
String str1 = input.nextLine();
Java Scanner next() reading range question
There is a little fault in your code//scnr.nextLine();
this line is important to read \n
before Chocolate Chips, If you wont use a dummy scnr.nextLine();
to read the new line then the new line will be read over here-
productName = scnr.nextLine();
System.out.println("2nd Name " + productName);
Here the productName
will have the value \n
and when it tries to read-
productPrice = scnr.nextInt();
System.out.println("2nd Price " + productPrice);
It expects to read an int
but finds an String
hence throws an exception.
Integer.parseInt(scanner.nextLine()) vs scanner.nextInt()
There are 2 observations :
- Using
myScannerInstance.nextInt()
leaves behind a new line character. So, if you callnextLine()
afternextInt()
, thenextLine()
will read the new line character instead of the actual data. Consequently, you will have to add anothernextLine()
after thenextInt()
to gobble up that dangling new-line character.nextLine()
doesn't leave behind a new line character.
code :
int age=myScannerInstance.nextInt();
String name = myScannerInstance.nextLine();// here the actual name will not be read. The new line character will be read.
nextInt()
will again go back to the underlying stream and read. IO calls take time (expensive). It will do lot of checks to get the next integer.nextLine()
will do those checks only once. So, if you callnextLine()
once and read 5 integers (as a single line String), split them and parse them as integers (usingInteger.parseInt()
), it will be faster and more efficient than reading each int individually.
Using nextLine()
+ parseInt()
will give you enormous performance benefit when you are running a very large loop.
Usage :
Using nextInt()
gives you an additional advantage wherein you will get an exception if the input text is not an integer. example 123
is accepted.. 123sdsa
will throw an InputMismatchException
. So, you can catch it and handle it appropriately.
Using nextLine()
will read the entire line, so, it will read the entire String sada1231
and then fail with NumberFormatException
if it cannot parse the String as a number. You will have to handle that exception.
Generally, one nextLine()
/ nextInt()
call won't make much of a difference. If you have a loop or if you are reading lot of data, then using readLine()
with parseInt()
will be very efficient.
Why multiple nextInt() works?
I have analyzed your question with debugging JRE Scanner class methods. When you called nextInt
function, Scanner looks current buffer. If there is no available input, started listening to the keyboard until you press Enter
key, whole keyboard characters appended to the buffer and tried to match that it is an integer or not. When it is found an integer nextInt
returns the value and increments the buffer's position index. Next step, you called the nextInt
again, and there is only \n
character, then it is discarded and waited for the next integer pattern. Also, the buffer's next character is \n
again. When you called nextLine
it looks to the buffer and prints an empty line. So second nextLine
is starting with empty text.
Maybe it can be confusing. Let's look at the scenario:
Note: Index ^
represents the buffer's reading position.
- Step
i1 = input.nextInt();
keyboard = 1 2 {Enter}
buffer = | 1 | 2 | \n |
index = ^
returns 12
and the next buffer position is located to \n
- Step
i2 = input.nextInt();
keyboard = 3 4 {Enter}
buffer = | 1 | 2 | \n | 3 | 4 | \n |
index = ^
returns 34
and the next buffer position is located to second \n
- Step
input.nextLine();
Buffer has \n
character, so Scanner does not wait for keyboard and returns the value.
buffer = | 1 | 2 | \n | 3 | 4 | \n |
index = ^
returns empty text
- Step
s1 = input.nextLine();
keyboard = test {Enter}
buffer = | 1 | 2 | \n | 3 | 4 | \n | t | e | s | t | \n |
index = ^
returns test
Related Topics
When to Use a List Over an Array in Java
Apache Spark - Foreach VS Foreachpartition When to Use What
Is Executorservice (Specifically Threadpoolexecutor) Thread Safe
Sum All the Elements Java Arraylist
Process Thymeleaf Variable as HTML Code and Not Text
In Java Lambda's Why Is Getclass() Called on a Captured Variable
Using Ntlm Authentication in Java Applications
Accessing Kotlin Extension Functions from Java
How to Use Regular Expressions in Web.Xml Url Patterns
Why Should I Override Hashcode() When I Override Equals() Method
Hibernate Bidirectional @Manytoone, Updating the Not Owning Side Not Working
How to Determine If a String Has Non-Alphanumeric Characters
Determining Current Call Stack (For Diagnostic Purposes)
How to Find a Definitive Selenium Webdriver to Firefox Compatibility Matrix