1. The Hook (The "Byte-Sized" Intro)
- In a Nutshell: Scanner (java.util) parses input from console, files, strings.
- Methods: next() (read word), nextLine() (read line), nextInt()/nextDouble() (read primitives), hasNext() (check availability). Console (System.console()) reads secure input: readLine(), readPassword() (hides input). Scanner = versatile parser (tokens, delimiters, regex). Console = secure terminal I/O. Scanner.nextLine() gotcha: Leaves newline in buffer after nextInt()!
Think of restaurant order. Scanner = waiter taking order piece-by-piece ("large", "pepperoni", "pizza"). nextInt() = "how many toppings?", nextLine() = "any special requests?". Console = secret password (kitchen staff can't see)!
2. Conceptual Clarity (The "Simple" Tier)
💡 The Analogy
- Scanner: Smart receptionist (breaks sentence into tokens/words)
- next(): Read one word at a time ("Hello" from "Hello World")
- nextLine(): Read entire sentence ("Hello World")
- Console: Password-protected safe (hides sensitive input)
3. Technical Mastery (The "Deep Dive")
Scanner Source Types
| Source | Constructor | Use Case |
|---|---|---|
| Console | new Scanner(System.in) | User input |
| File | new Scanner(new File("file.txt")) | File parsing |
| String | new Scanner("data") | String parsing |
| InputStream | new Scanner(stream) | Stream parsing |
4. Interactive & Applied Code
java
import java.io.*;
import java.util.*;
public class ScannerConsoleDemo {
public static void main(String[] args) {
demonstrateScannerBasics();
demonstrateScannerFile();
demonstrateScannerDelimiters();
demonstrateConsole();
demonstrateCommonPitfall();
}
// Scanner basics (console input)
static void demonstrateScannerBasics() {
System.out.println("=== SCANNER BASICS ===");
// Create scanner for manual testing
String input = "John 25 75000.50";
Scanner scanner = new Scanner(input);
// Read different types
String name = scanner.next(); // Reads "John"
int age = scanner.nextInt(); // Reads 25
double salary = scanner.nextDouble(); // Reads 75000.50
System.out.println("Name: " + name);
System.out.println("Age: " + age);
System.out.println("Salary: " + salary);
scanner.close();
}
// Reading from file
static void demonstrateScannerFile() {
System.out.println("\n=== SCANNER FILE ===");
try {
// Create sample file
PrintWriter writer = new PrintWriter("data.txt");
writer.println("Alice 30");
writer.println("Bob 25");
writer.println("Carol 35");
writer.close();
// Read file with Scanner
Scanner scanner = new Scanner(new File("data.txt"));
System.out.println("Reading file:");
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
System.out.println(" " + line);
// Parse line
Scanner lineScanner = new Scanner(line);
if (lineScanner.hasNext()) {
String name = lineScanner.next();
int age = lineScanner.nextInt();
System.out.println(" Parsed: " + name + " is " + age);
}
lineScanner.close();
}
scanner.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
// Custom delimiters
static void demonstrateScannerDelimiters() {
System.out.println("\n=== SCANNER DELIMITERS ===");
// CSV data
String csv = "Alice,30,Seattle|Bob,25,NYC|Carol,35,LA";
// Use | as delimiter
Scanner scanner = new Scanner(csv).useDelimiter("\\|");
while (scanner.hasNext()) {
String record = scanner.next();
System.out.println("Record: " + record);
// Parse each record with , delimiter
Scanner fieldScanner = new Scanner(record).useDelimiter(",");
String name = fieldScanner.next();
int age = fieldScanner.nextInt();
String city = fieldScanner.next();
System.out.println(" Name: " + name + ", Age: " + age + ", City: " + city);
fieldScanner.close();
}
scanner.close();
}
// Console class (secure input)
static void demonstrateConsole() {
System.out.println("\n=== CONSOLE ===");
Console console = System.console();
if (console == null) {
System.out.println("Console not available (running in IDE?)");
System.out.println("Console works in terminal: java MyProgram");
return;
}
// Read line
String username = console.readLine("Enter username: ");
// Read password (hidden input!)
char[] password = console.readPassword("Enter password: ");
System.out.println("Username: " + username);
System.out.println("Password: " + "*".repeat(password.length));
// Clear password from memory (security!)
Arrays.fill(password, ' ');
}
// Common pitfall: nextInt() + nextLine()
static void demonstrateCommonPitfall() {
System.out.println("\n=== COMMON PITFALL ===");
String input = "25\nJohn Doe";
Scanner scanner = new Scanner(input);
// Read age
int age = scanner.nextInt(); // Reads "25", leaves "\n" in buffer!
System.out.println("Age: " + age);
// ❌ PROBLEM: nextLine() reads leftover "\n"
scanner.nextLine(); // Consume newline!
// ✅ NOW we can read the full line
String name = scanner.nextLine(); // Reads "John Doe"
System.out.println("Name: " + name);
scanner.close();
}
}
// Real-world example: Interactive menu
class InteractiveMenu {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.println("\n=== MENU ===");
System.out.println("1. Option 1");
System.out.println("2. Option 2");
System.out.println("0. Exit");
System.out.print("Choice: ");
if (scanner.hasNextInt()) {
int choice = scanner.nextInt();
scanner.nextLine(); // Consume newline!
switch (choice) {
case 1:
System.out.println("You chose Option 1");
break;
case 2:
System.out.println("You chose Option 2");
break;
case 0:
System.out.println("Goodbye!");
scanner.close();
return;
default:
System.out.println("Invalid choice");
}
} else {
System.out.println("Invalid input!");
scanner.next(); // Consume invalid input
}
}
}
}5. The Comparison & Decision Layer
| Scenario | Use This | Why |
|---|---|---|
| Console input | Scanner | Easy parsing |
| File parsing | Scanner | Token-based |
| Secure password | Console.readPassword() | Hides input |
| Line-by-line | BufferedReader | Faster |
| CSV parsing | Scanner with delimiters | Flexible |
6. The "Interview Corner" (The Edge)
The "Killer" Interview Question: "Why does nextLine() return empty after nextInt()?" Answer: nextInt() doesn't consume newline!
java
Scanner scanner = new Scanner("25\nJohn");
int age = scanner.nextInt(); // Reads "25", buffer = "\nJohn"
String name = scanner.nextLine(); // Reads "\n" → empty!
// ✅ SOLUTION: Consume newline
int age = scanner.nextInt();
scanner.nextLine(); // Discard "\n"
String name = scanner.nextLine(); // Now reads "John"Pro-Tip: Always close Scanner:
java
// ❌ RESOURCE LEAK
Scanner scanner = new Scanner(System.in);
scanner.nextLine();
// Forgot to close!
// ✅ AUTO-CLOSE
try (Scanner scanner = new Scanner(System.in)) {
scanner.nextLine();
} // Auto-closedBut: Closing Scanner closes underlying stream (System.in)!
For System.in, don't use try-with-resources (closes System.in).