Hi! Our lesson today will be special! In today's lesson, we'll talk about Java Scanner Class.
Previously, the process of completing tasks and writing programs was simple: we write some code, run the main() method, the program does what is required, and we're done.
But now everything will change! Today we'll learn how to really interact with the program: we'll teach it how to respond to our actions!
Before we start analyzing the code, have you ever had to deal with a device like a scanner?
Probably. The insides of a scanner are quite complicated, but the basic idea of how it works is very simple: it reads data that the user provides (such as a passport or insurance policy) and stores this information in memory (for example, as an image).
Today you're going to create your own scanner! Of course, it won't be able handle paper documents, but text will be no problem for it :)
Let's go!
Java's Scanner class
First and foremost, we must get acquainted with the java.util.Scanner class. Its functionality is very simple. Like a real scanner, it reads data from a source that you specify. For example, a string, a file, the console. Next, it recognizes the information and processes it appropriately. Here's the simplest example:
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner("It matters not how strait the gate,\n" +
"How charged with punishments the scroll,\n" +
"I am the master of my fate,\n" +
"I am the captain of my soul");
String s = scanner.nextLine();
System.out.println(s);
}
}
We've created a scanner object, and specified its data source (a string of text).
The nextLine() method accesses the data source (our text with a quatrain), finds the next unread line (which is the first line in this case), and returns it. Then we display it on the console:
Console output:
It matters not how strait the gate,
We can use the nextLine() method several times and display the entire poem excerpt:
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner("It matters not how strait the gate,\n" +
"How charged with punishments the scroll,\n" +
"I am the master of my fate,\n" +
"I am the captain of my soul");
String s = scanner.nextLine();
System.out.println(s);
s = scanner.nextLine();
System.out.println(s);
s = scanner.nextLine();
System.out.println(s);
s = scanner.nextLine();
System.out.println(s);
}
}
Each time, our scanner takes one step forward and reads the next line.
The program's output is displayed:
It matters not how strait the gate,
How charged with punishments the scroll,
I am the master of my fate,
I am the captain of my soul
As we've already said, the scanner's data source doesn't have to be a string.
For example, it could be the console. Some exciting news for you: previously, we just displayed data there, but now we'll read data from the keyboard!
Let's see what else the Scanner class does:
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter a number:");
int number = sc.nextInt();
System.out.println("Thanks! You entered the number " + number);
}
}
The nextInt() method reads and returns the entered number. In our program, we use it to assign a value to the variable number.
It's already more like a real scanner! The program asks the user to enter any number. After the user has done this, the program thanks the user, displays the result, and finishes.
But we still have a serious problem. The user might make a mistake and enter something wrong.
Here is an example where our current program stops working:
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter a number:");
int number = sc.nextInt();
System.out.println("Thanks! You entered the number " + number);
}
}
Let's try entering the string "CodeGym" instead a number:
Console output:
Enter a number:
CodeGym
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:864)
at java.util.Scanner.next(Scanner.java:1485)
at java.util.Scanner.nextInt(Scanner.java:2117)
at java.util.Scanner.nextInt(Scanner.java:2076)
at Main.main(Main.java:10) Process finished with exit code 1
Uh, oh. We're in big trouble -_-
To avoid such situations, we need to come up with a way to verify the data entered by the user. For example, if the user enters anything other than a number, it would be good to display a warning that the entered information is not a number. And if the information is okay, then we could confirmation.
But this would require us to "look into the future" to see what's coming in our stream. Can Scanner do this?
And how! And it has a slew of methods for doing this:
hasNextInt() — This method checks whether the next chunk of input data is a number (returns true or false, as appropriate).
hasNextLine() — This method checks whether the next chunk of input is a string.
hasNextByte(), hasNextShort(), hasNextLong(), hasNextFloat(), hasNextDouble() — All these methods perform similar checks for the remaining data types.
Let's try changing our number-reading program:
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter a number:");
if (sc.hasNextInt()) {
int number = sc.nextInt();
System.out.println("Thanks! You entered the number " + number);
} else {
System.out.println("Sorry, but this is clearly not a number. Restart the program and try again!");
}
}
}
Now our program checks whether the next character entered is a number. And it displays confirmation only if it is. If the input doesn't pass the check, the program takes note and asks the user to try again.
Basically, you can communicate with the Scanner object and find out in advance what data type awaits you. A number, string, or something else? A number? And what kind? An int, short, long?"
This flexibility gives you the opportunity to build program logic that depends on the user's behavior. We should make note of another important method: useDelimiter().
You pass a string to this method. The string contains the characters you want to use as separators or delimiters.
For example, suppose we suddenly became interested in Japanese poetry, and decided to use our scanner to read some haiku written by the great poet Matsuo Bashō.
Even if three different verses are passed to us as one awkward string, we can easily split them and render them beautifully:
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner("On a withered branch'" +
"A crow has alighted.'" +
"Nightfall in autumn." +
"''***''" +
"Such a moon above,'" +
"Like a tree cut at the root:'" +
"he fresh cut is white." +
"''***''" +
"How the river floods!'" +
"A heron wanders on short legs,'" +
"Knee-deep in the water.");
scan.useDelimiter("'");
while (scan.hasNext()) {
System.out.println(scan.next());
}
scan.close();
}
}
We use "\n/*/*/*" (new line character and three asterisks) as our delimiter.
As a result, we have beautiful console output, just like in books:
On a withered branch
A crow has alighted.
Nightfall in autumn.
***
Such a moon above,
Like a tree cut at the root:
The fresh cut is white.
***
How the river floods!
A heron wanders on short legs,
Knee-deep in the water.
This example has one more method that we must absolutely point out: close(). Like any object working with I/O streams, the scanner must be closed when it is done so it stops consuming the computer's resources. Never forget the close() method!
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter a number:");
int number = sc.nextInt();
System.out.println("Thanks! You entered the number " + number);
sc.close(); // Now we've done everything right!
}
}
That's it! As you can see, for how helpful it is, the Scanner class is quite easy to use! :)
To reinforce what you learned, we suggest you watch a video lesson from our Java CourseMore reading: |
---|
GO TO FULL VERSION