Java Scanner hasNext() vs. hasNextLine()

1. Overview

The Scanner class is a handy tool that can parse primitive types and strings using regular expressions and was introduced into the java.util package in Java 5.

In this short tutorial, we’ll talk about its hasNext() and hasNextLine() methods. Even though these two methods may look pretty similar at first, they’re actually doing quite different checks.

You can also read more about the versatile Scanner class in the quick guide here.

2. hasNext()

2.1. Basic Usage

The hasNext() method checks if the Scanner has another token in its input. Scanner breaks its input into tokens using a delimiter pattern, which matches whitespace by default. That is, hasNext() checks the input and returns true if it has another non-whitespace character.

We should also note a few details about the default delimiter:

  • Whitespace includes not only the space character, but also tab space (\t), line feed (\n), and even more characters
  • Continuous whitespace characters are treated as a single delimiter
  • The blank lines at the end of the input are not printed — that is, hasNext() returns false for blank lines

Let’s take a look at an example of how hasNext() works with the default delimiter. First, we’ll prepare an input string to help us explore Scanner‘s parsing result:

String INPUT = new StringBuilder()
    .append("magic\tproject\n")
    .append("     database: oracle\n")
    .append("dependencies:\n")
    .append("spring:foo:bar\n")
    .append("\n")  // Note that the input ends with a blank line
    .toString();

Next, let’s parse the input and print the result:

Scanner scanner = new Scanner(INPUT);
while (scanner.hasNext()) {
    log.info(scanner.next());
}
log.info("--------OUTPUT--END---------")

If we run the above code, we’ll see the console output:

[DEMO]magic
[DEMO]project
[DEMO]database:
[DEMO]oracle
[DEMO]dependencies:
[DEMO]spring:foo:bar
[DEMO]--------OUTPUT--END---------

2.2. With Custom Delimiter

So far, we’ve looked at hasNext() with the default delimiter. The Scanner class provides a useDelimiter(String pattern) method that allows us to change the delimiter. Once the delimiter is changed, the hasNext() method will do the check with the new delimiter instead of the default one.

Let’s see another example of how hasNext() and next() work with a custom delimiter. We’ll reuse the input from the last example.

After the scanner parses a token matching the string “dependencies:“, we’ll change the delimiter to a colon ( : ) so that we can parse and extract each value of the dependencies:

while (scanner.hasNext()) {
    String token = scanner.next();
    if ("dependencies:".equals(token)) {
        scanner.useDelimiter(":");
    }
    log.info(token);
}
log.info("--------OUTPUT--END---------");

Let’s see the resulting output:

[DEMO]magic
[DEMO]project
[DEMO]database:
[DEMO]oracle
[DEMO]dependencies:
[DEMO]
spring
[DEMO]foo
[DEMO]bar


[DEMO]--------OUTPUT--END---------

Great! We’ve successfully extracted the values in “dependencies“, however, there are some unexpected line-break problems. We’ll see how to avoid those in the next section.

2.3. With regex as Delimiter

Let’s review the output in the last section. First, we noticed that there’s a line break (\n) before “spring“. We’ve changed the delimiter to “:” after the “dependencies:” token was fetched. The line break after the “dependencies:” now becomes the part of the next token. Therefore, hasNext() returned true and the line break was printed out.

For the same reason, the line feed after “hibernate” and the last blank line become the part of the last token, so two blank lines are printed out together with “hibernate“.

If we can make both colon and whitespace as the delimiter, then the “dependencies” values will be correctly parsed and our problem will be solved. To achieve that, let’s change the useDelimiter(“:”) call:

scanner.useDelimiter(":|\\s+");

The “:|\\s+” here is a regular expression matching a single “:” or one or more whitespace characters. With this fix, the output turns into:

[DEMO]magic
[DEMO]project
[DEMO]database:
[DEMO]oracle
[DEMO]dependencies:
[DEMO]spring
[DEMO]foo
[DEMO]bar
[DEMO]--------OUTPUT--END---------

3. hasNextLine()

The hasNextLine() method checks to see if there’s another line in the input of the Scanner object, no matter if the line is blank or not.

Let’s take the same input again. This time, we’ll add line numbers in front of each line in the input using hasNextLine() and nextLine() methods:

int i = 0;
while (scanner.hasNextLine()) {
    log.info(String.format("%d|%s", ++i, scanner.nextLine()));
}
log.info("--------OUTPUT--END---------");

Now, let’s take a look at our output:

[DEMO]1|magic	project
[DEMO]2|     database: oracle
[DEMO]3|dependencies:
[DEMO]4|spring:foo:bar
[DEMO]5|
[DEMO]--------OUTPUT--END---------

As we expected, the line numbers are printed, and the last blank line is there, too.

4. Conclusion

In this article, we’ve learned that Scanner‘s hasNextLine() method checks if there is another line in the input, no matter if the line is blank or not, while hasNext() uses a delimiter to check for another token.

As always, the complete source code for the examples is available over on GitHub.

Related posts:

Java 14 Record Keyword
Spring’s RequestBody and ResponseBody Annotations
Java Program to Check whether Graph is a Bipartite using BFS
Java Program to Implement Sorted List
Java Program to Generate All Possible Combinations of a Given List of Numbers
The Thread.join() Method in Java
Java Program to Implement Solovay Strassen Primality Test Algorithm
Java Program to Implement the MD5 Algorithm
Receive email by java client
Calling Stored Procedures from Spring Data JPA Repositories
A Guide To UDP In Java
Notify User of Login From New Device or Location
Java Program to Implement Coppersmith Freivald’s Algorithm
A Guide to Concurrent Queues in Java
Intro to Spring Boot Starters
Lập trình đa luồng với Callable và Future trong Java
Java Program to Implement Gift Wrapping Algorithm in Two Dimensions
Biến trong java
Java Program to Find Inverse of a Matrix
Introduction to Spring Cloud Rest Client with Netflix Ribbon
Java Program to Implement Knight’s Tour Problem
Unsatisfied Dependency in Spring
Java Program to Check the Connectivity of Graph Using DFS
Java Web Services – Jersey JAX-RS – REST và sử dụng REST API testing tools với Postman
Java Program to Implement Binary Tree
Java Program to Delete a Particular Node in a Tree Without Using Recursion
Guide to the Volatile Keyword in Java
A Guide to Java SynchronousQueue
Spring Data – CrudRepository save() Method
Extract network card address
Spring Boot Integration Testing with Embedded MongoDB
Java Program to Generate All Pairs of Subsets Whose Union Make the Set