☕ Java
Scanner Class
The Scanner class (java.util.Scanner) is the standard way to read user input from the keyboard in Java. It wraps System.in and provides methods to parse tokens as specific types — nextInt(), nextDouble(), nextLine(), next() — without manually converting strings. Scanner also works with files and strings as input sources.
Creating a Scanner and Basic Reading
Scanner must be imported from java.util. For keyboard input, wrap System.in. Scanner reads tokens separated by whitespace (spaces, tabs, newlines) by default. Each next() or nextXxx() call reads the next token and advances the internal cursor. The Scanner should be closed when no longer needed, though closing System.in should be done carefully as it cannot be reopened.
Java
import java.util.Scanner;
public class BasicInput {
public static void main(String[] args) {
// ── Create Scanner for keyboard input: ───────────────────────
Scanner scanner = new Scanner(System.in);
// ── Read a String token (one word): ───────────────────────────
System.out.print("Enter your name: ");
String name = scanner.next(); // reads one word
System.out.println("Hello, " + name);
// ── Read an integer: ──────────────────────────────────────────
System.out.print("Enter your age: ");
int age = scanner.nextInt();
System.out.println("Age: " + age);
// ── Read a double: ────────────────────────────────────────────
System.out.print("Enter your height (m): ");
double height = scanner.nextDouble();
System.out.printf("Height: %.2f m%n", height);
// ── Read a boolean: ───────────────────────────────────────────
System.out.print("Active? (true/false): ");
boolean active = scanner.nextBoolean();
System.out.println("Active: " + active);
// ── Read a full line: ─────────────────────────────────────────
scanner.nextLine(); // consume leftover newline after nextBoolean()
System.out.print("Enter your address: ");
String address = scanner.nextLine(); // reads entire line
System.out.println("Address: " + address);
// ── Close scanner when done: ──────────────────────────────────
scanner.close();
}
}
// ── Input/Output example: ─────────────────────────────────────────────
// Enter your name: Alice
// Hello, Alice
// Enter your age: 30
// Age: 30
// Enter your height (m): 1.68
// Height: 1.68 m
// Active? (true/false): true
// Active: true
// Enter your address: 123 Main Street
// Address: 123 Main StreetScanner Methods Reference
Scanner provides a next method for each primitive type plus String. Each method has a corresponding hasNextXxx method that checks whether the next token can be read as that type without consuming it — essential for loops and validation.
Java
Scanner sc = new Scanner(System.in);
// ── Reading methods: ──────────────────────────────────────────────────
String word = sc.next(); // next whitespace-delimited token
String line = sc.nextLine(); // entire line including spaces
int i = sc.nextInt(); // next token as int
long l = sc.nextLong(); // next token as long
double d = sc.nextDouble(); // next token as double
float f = sc.nextFloat(); // next token as float
boolean b = sc.nextBoolean(); // next token as boolean (true/false)
byte by = sc.nextByte(); // next token as byte
short s = sc.nextShort(); // next token as short
// ── Checking methods (non-consuming): ────────────────────────────────
boolean hasToken = sc.hasNext(); // any token available?
boolean hasLine = sc.hasNextLine(); // any line available?
boolean hasInt = sc.hasNextInt(); // next token parseable as int?
boolean hasDouble = sc.hasNextDouble(); // next token parseable as double?
boolean hasBool = sc.hasNextBoolean(); // next token true or false?
// ── Validated input loop — keep asking until valid int: ───────────────
Scanner scanner = new Scanner(System.in);
int number = 0;
while (true) {
System.out.print("Enter an integer: ");
if (scanner.hasNextInt()) {
number = scanner.nextInt();
break;
} else {
System.out.println("Invalid — please enter a whole number.");
scanner.next(); // discard the invalid token
}
}
System.out.println("You entered: " + number);
// ── Read until end of input (file or piped input): ────────────────────
Scanner sc2 = new Scanner(System.in);
while (sc2.hasNextLine()) {
String inputLine = sc2.nextLine();
System.out.println("Read: " + inputLine);
}
// ── Read multiple values on one line: ────────────────────────────────
// Input: "Alice 30 1.68"
Scanner sc3 = new Scanner(System.in);
String n = sc3.next();
int a = sc3.nextInt();
double h = sc3.nextDouble();
System.out.printf("%s is %d years old and %.2fm tall%n", n, a, h);The nextLine() After nextInt() Problem
The most common Scanner pitfall occurs when mixing nextInt() (or any nextXxx() for primitives) with nextLine(). The nextInt() method reads the integer but leaves the newline character in the buffer. The immediately following nextLine() then reads that leftover newline instead of the next line of user input, returning an empty string. The fix is to call nextLine() once after nextInt() to consume the leftover newline before reading the next line.
Java
// ── The problem: nextLine() returns empty string: ────────────────────
Scanner sc = new Scanner(System.in);
System.out.print("Enter age: ");
int age = sc.nextInt();
// User types: 25 ↵
// Buffer after nextInt(): "
" ← leftover newline
System.out.print("Enter name: ");
String name = sc.nextLine();
// nextLine() reads up to the next
— finds the leftover
immediately
// Returns "" (empty string) without waiting for user input!
System.out.println("Age: " + age);
System.out.println("Name: '" + name + "'");
// Output:
// Enter age: 25
// Enter name: ← skipped! user never got to type
// Age: 25
// Name: '' ← empty!
// ── Fix 1: consume leftover newline with an extra nextLine(): ─────────
Scanner sc2 = new Scanner(System.in);
System.out.print("Enter age: ");
int age2 = sc2.nextInt();
sc2.nextLine(); // consume the leftover "
"
System.out.print("Enter name: ");
String name2 = sc2.nextLine(); // now reads correctly
System.out.println("Age: " + age2 + ", Name: " + name2);
// ── Fix 2: read everything as lines, then parse: ──────────────────────
Scanner sc3 = new Scanner(System.in);
System.out.print("Enter age: ");
int age3 = Integer.parseInt(sc3.nextLine().trim());
System.out.print("Enter name: ");
String name3 = sc3.nextLine(); // no problem — only using nextLine()
System.out.println("Age: " + age3 + ", Name: " + name3);
// ── Rule of thumb: ────────────────────────────────────────────────────
// Mixing nextInt()/nextDouble()/etc. with nextLine() in sequence
// always requires an extra nextLine() call in between.
// OR — use only nextLine() for all input and parse manually.Scanner with Files and Strings
Scanner is not limited to keyboard input. It can read from files, strings, and any InputStream. Reading from a file with Scanner is convenient for small files where token-based or line-by-line parsing is needed. Reading from a String is useful in tests and when parsing already-loaded content.
Java
import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;
// ── Scanner reading from a file: ─────────────────────────────────────
// data.txt contents:
// Alice 95
// Bob 87
// Charlie 72
try (Scanner fileScanner = new Scanner(new File("data.txt"))) {
while (fileScanner.hasNextLine()) {
String studentName = fileScanner.next();
int studentScore = fileScanner.nextInt();
System.out.printf("%-10s → %d%n", studentName, studentScore);
}
} catch (FileNotFoundException e) {
System.err.println("File not found: " + e.getMessage());
}
// Output:
// Alice → 95
// Bob → 87
// Charlie → 72
// ── Scanner with file using Path (Java 11+): ──────────────────────────
try (Scanner sc = new Scanner(Path.of("data.txt"))) {
while (sc.hasNextLine()) {
System.out.println(sc.nextLine());
}
} catch (IOException e) {
System.err.println("I/O error: " + e.getMessage());
}
// ── Scanner reading from a String: ───────────────────────────────────
String data = "10 20 30 40 50";
Scanner strScanner = new Scanner(data);
int sum = 0;
while (strScanner.hasNextInt()) {
sum += strScanner.nextInt();
}
System.out.println("Sum: " + sum); // Sum: 150
strScanner.close();
// ── Scanner with custom delimiter: ────────────────────────────────────
// Parse CSV line: "Alice,30,Engineer"
String csv = "Alice,30,Engineer";
Scanner csvScanner = new Scanner(csv).useDelimiter(",");
String csvName = csvScanner.next(); // Alice
int csvAge = csvScanner.nextInt(); // 30
String csvJob = csvScanner.next(); // Engineer
System.out.printf("%s (%d) — %s%n", csvName, csvAge, csvJob);
csvScanner.close();Related Topics in Java Basics
Variables in Java
A variable is just a named box in memory that holds a value. Java is strict about what goes in each box — you tell it the type upfront. Once you get this, the rest of Java clicks into place.
Data Types in Java
Java needs to know exactly what kind of data it's dealing with before it can store or process it. Integers, decimals, characters, true/false — each has its own type. Knowing which to use (and why) makes your programs efficient and bug-free.
Primitive Data Types
Java has eight primitive data types — the most basic building blocks for storing data. Unlike objects, primitives are stored directly in memory, making them fast and efficient. Understanding each type, its size, range, and when to use it is fundamental to writing correct Java programs.
Non-Primitive Data Types
Non-primitive data types — also called reference types — are everything beyond Java's eight primitives. Strings, arrays, classes, interfaces, enums, and records all fall into this category. They're more powerful than primitives, but they work differently in memory, comparison, and nullability. Understanding the distinction is essential for writing correct Java.