java.util. Scanner, hasNext... (); & next... (); Working with object memory

What's going on?! How do the methods of the Scanner class next... (); and hasNext... (); work with memory?

Example:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner console = new Scanner(System.in);
        
        boolean b = console.hasNextLine();
        String i = console.nextLine();
        String str = console.nextLine();
        
        System.out.println("Output:");
        System.out.println("i = " + i);
        System.out.println("str = " + str);
    }
}

When initializing the variable b, input from the console will be started. However, even when initializing the variable i, it is not required. The nextInt (); method for some reason just takes the same value that was entered a little earlier when calling the hasNextLine () method; But when initializing the str variable, it asks you to enter a new line.

Next more fun: Changing the type the i variable from String to int. When initializing the b variable, console input is activated. The same input is redirected to the nextInt (); method when initializing the i variable. And initialization of the str variable is skipped altogether! Do not ask to enter the next line.

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner console = new Scanner(System.in);

        boolean b = console.hasNextLine();
        int i = console.nextInt();
        String str = console.nextLine();

        System.out.println("Output:");
        System.out.println("i = " + i);
        System.out.println("str = " + str);
    }
}

Obviously, this is due to how these methods work with the memory of an object of the Scanner type, in this case, "console". But where all these chips and cases are painted in detail - I do not know. As well as what generally happens in the second case?! Please help!

Author: Rost, 2021-01-07

1 answers

First example

    boolean b = console.hasNextLine();

How can the program determine whether the next line will be entered? No way. The input file can be closed at any time. Therefore, the program is waiting for some data to be entered.

The input stream from the console is buffered line by line. Have you noticed that the line can be edited and the program does not see your actions until you click Enter?

The combination of these two factors makes the program wait until you enter the first line.

    String i = console.nextLine();

When this code is executed, the line is already entered and available to the program. The variable i is immediately filled with the value and we move on.

    String str = console.nextLine();

And the user hasn't entered the next line yet. The program stops and waits for you to edit the text and press Enter. After that, we move on.

Second example

    boolean b = console.hasNextLine();

Here everything is the same as in the example above.

    int i = console.nextInt();

Here the string is already read, we start to parse it: skip the spaces, read the sign numbers and numbers and stop at the first space character. This can be a line feed, a space, or a tab, but not only.

The number is read from the input stream character by character. When an unsuitable character is found, it is "returned" to the stream, so that when you continue reading, you will see it first.

Anyway, the line feed after reading the integer will remain in the stream.

    String str = console.nextLine();

Read the next line. But no, not the next one: we read the rest of the current one lines. If you clicked Enter right after the number, you will get an empty string.

Output

It is clear that nextInt and nextLine somehow do not work well with each other. This is understandable: nextInt is designed so as not to distinguish spaces from line feeds. nextLine - the opposite.

You can solve the problem radically: always read whole lines. If you do not need a string but an integer, then extract it from the string after reading:

String line = console.nextLine();
int i = Integer.parseInt(line, 10);

All the mechanics are well described in the official documentation on Scanner. Details related to buffering are omitted: the operating system forwards input in whole lines, etc.

 0
Author: Stanislav Volodarskiy, 2021-01-08 07:36:00