Java Scanner is a simple text parser, it can parse a file, input stream or string into primitive and string tokens using regexp.
It breaks an input into the tokens using delimiter regular expression (whitespace by default Character#isWhitespace(char)
).
Tokens can be converted into primitives (double, float, long, int, byte, short, boolean), number objects (BigDecimal, BigInteger) and String.
Scanner provides a bunch of methods to do that:
String next()
String nextLine()
double nextDouble()
float nextFloat()
int nextInt()
boolean nextBoolean()
BigDecimal nextBigDecimal()
and so on, no sense to mention all of available methods.
In general, Java Scanner API looks like an iterator pattern and consists of 4 steps:
- break input into tokens
- iterate through the tokens
- check
hasNext()
for each token - retrieve its value if its exist
The most popular use cases:
- read input from a console
- read lines from a file
- parse a string by the delimiter
Let’s take a deeper look at what is Scanner
in Java program on practical examples.
Read Input From Console
When you’re starting learning Java one of the first questions is: “How to take input from a keyboard in Java?”.
You can do it using Scanner
class.
For example, we want to enter numbers and show a sum at the end.
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("PLEASE, ENTER A INT VALUE, 'X' TO STOP");
List<Integer> numbers = new ArrayList<>();
while (scanner.hasNext()) {
try {
int value = scanner.nextInt();
numbers.add(value);
System.out.println("RECEIVED NUMBER: " + value);
} catch (InputMismatchException e) {
String next = scanner.next();
if ("X".equalsIgnoreCase(next)) {
break;
} else {
System.out.println("INCORRECT NUMBER");
}
}
}
System.out.println("SUM IS: " + numbers.stream().mapToInt(i -> i).sum());
scanner.close();
}
You can ask me: “How do you import scanner in Java?”. Easy – import java.util.Scanner
.
new Scanner(System.in)
is waiting for user input, we’re iterating through each input value and putting this numbers into the list.
If a user enters “X” we stop a Java program.
Afterward, we’re calculating a sum of the numbers using Stream API and close a scanner.
Read Lines From a File
I already showed this example in my article “3 Ways How To Read File Line by Line in Java“, but I think it makes sense to duplicate it here as well.
package com.explainjava;
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
public class ReadFile {
public static void main(String[] args) throws IOException {
Scanner scanner = new Scanner(new File("/Users/dshvechikov/file"));
while(scanner.hasNextLine()) {
System.out.println(scanner.nextLine());
}
scanner.close();
}
}
A scanner parses a file and reads each line.
You can use InputStream
or Path
instead of File
class – it’s more or less the same.
Parse String By Delimiter
For example, you need to split a string by delimiter and parse int values.
To scan using delimiter we have to use useDelimiter(pattern)
method.
Scanner scanner = new Scanner("1|2|3|4|5|6").useDelimiter("\\|");
while(scanner.hasNext()) {
System.out.println(scanner.nextInt());
}
scanner.close();
Since Java 9 you can get a stream of tokens and handle it in a functional way:
Scanner scanner = new Scanner("1|2|3|4|5|6").useDelimiter("\\|");
scanner.tokens().forEach(System.out::print);
scanner.close();
One more interesting method is Stream findAll(Pattern pattern)
.
It returns a stream of match results where you can extract groups.
Example:
Scanner scanner = new Scanner("1a|2b|3c|4d|5e|6f").useDelimiter("\\|");
scanner.findAll("([0-9]{1})([a-z]{1})").forEach(matchResult -> {
System.out.println("FULL STRING: " + matchResult.group(0) + ". NUMBER: " + matchResult.group(1) + ", LETTER: " + matchResult.group(2));
});
scanner.close();
Output:
FULL STRING: 1a. NUMBER: 1, LETTER: a
FULL STRING: 2b. NUMBER: 2, LETTER: b
FULL STRING: 3c. NUMBER: 3, LETTER: c
FULL STRING: 4d. NUMBER: 4, LETTER: d
FULL STRING: 5e. NUMBER: 5, LETTER: e
FULL STRING: 6f. NUMBER: 6, LETTER: f
There are 3 steps:
- Split a string by “|” character into tokens
- Parse each token by regexp into groups
- Extract groups
In this example, I have 3 groups – source token, number, and letter.
Conclusion
Java Scanner class is a really powerful instrument to parse a file, input stream or string.
It provides methods to convert tokens into primitives and some object types, sometimes it’s really useful.