Input and flow control in Java — Scanner, if/else and switch from scratch

Input and flow control in Java cover the tools that make a program interactive and intelligent — reading data from the user and making decisions based on it. If you already know Python’s input(), if/elif/else and C’s switch, you already understand the concepts. What changes is the syntax and one important new class: Scanner.

Scanner — reading user input

In Python you used input() — a built-in function available anywhere. In Java there’s no built-in equivalent. You need to create a Scanner object and import the class first:

import java.util.Scanner;    // import at top of file, before the class

public class InputDemo {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        System.out.print("Enter your name: ");
        String name = scanner.nextLine();

        System.out.print("Enter your age: ");
        int age = scanner.nextInt();

        System.out.printf("Hello, %s! You are %d years old.%n", name, age);

        scanner.close();    // good practice — release the resource
    }
}

Breaking down Scanner scanner = new Scanner(System.in):

Scanner — the class name. It lives in java.util so you must import it.

scanner — the variable name. Convention: lowercase, camelCase. You can name it anything but scanner or sc are standard.

new Scanner(System.in) — creates a new Scanner object connected to System.in (standard input — the keyboard). new is the keyword that creates objects in Java.

Scanner methods for different types

Scanner sc = new Scanner(System.in);

String line   = sc.nextLine();     // reads a full line (including spaces)
String word   = sc.next();         // reads one word (stops at space)
int    i      = sc.nextInt();      // reads an integer
double d      = sc.nextDouble();   // reads a decimal number
long   l      = sc.nextLong();     // reads a long integer
boolean b     = sc.nextBoolean();  // reads true or false
char   c      = sc.next().charAt(0); // reads a single character

The nextLine() trap after nextInt()

This is the most common Scanner bug in FP2. When you call nextInt() it reads the number but leaves the newline character \n (from pressing Enter) in the input buffer. The next nextLine() reads that leftover newline instead of waiting for user input:

Scanner sc = new Scanner(System.in);

System.out.print("Age: ");
int age = sc.nextInt();          // reads "20", leaves "\n" in buffer

System.out.print("Name: ");
String name = sc.nextLine();     // reads the leftover "\n" — gets empty string!

System.out.println("Name: " + name);    // → prints "Name: " (empty)

Fix: add sc.nextLine() after any nextInt(), nextDouble() or similar to consume the leftover newline:

System.out.print("Age: ");
int age = sc.nextInt();
sc.nextLine();                   // consume leftover newline

System.out.print("Name: ");
String name = sc.nextLine();     // now correctly waits for input

Python vs Java input

# Python
name  = input("Name: ")
age   = int(input("Age: "))
grade = float(input("Grade: "))
// Java
Scanner sc = new Scanner(System.in);
System.out.print("Name: ");
String name = sc.nextLine();
System.out.print("Age: ");
int age = sc.nextInt();
System.out.print("Grade: ");
double grade = sc.nextDouble();

if / else if / else

The structure is identical to C and nearly identical to Python — the difference is else if instead of elif, parentheses around the condition, and curly braces instead of indentation:

# Python
if grade >= 9:
    print("Outstanding")
elif grade >= 7:
    print("Merit")
elif grade >= 5:
    print("Passed")
else:
    print("Failed")
// Java
if (grade >= 9.0) {
    System.out.println("Outstanding");
} else if (grade >= 7.0) {
    System.out.println("Merit");
} else if (grade >= 5.0) {
    System.out.println("Passed");
} else {
    System.out.println("Failed");
}

Three differences from Python: parentheses around the condition are mandatory, elif becomes else if (two words), and { } delimit blocks instead of indentation.

Always use curly braces

With a single statement you can omit the curly braces:

if (grade >= 5.0)
    System.out.println("Passed");    // works — one statement

But this creates the classic bug when you add a second line thinking it’s inside the if:

if (grade >= 5.0)
    System.out.println("Passed");
    System.out.println("Congratulations");   // ALWAYS executes — NOT inside the if

The recommendation for FP2: always use curly braces, even for single-statement blocks. The extra two characters prevent hours of debugging.

Comparison and logical operators

// Comparison — identical to Python and C
==    !=    >    <    >=    <=

// Logical — different symbols from Python
// Python: and    or    not
// Java:   &&     ||    !

if (grade >= 5.0 && grade <= 10.0) { }    // both conditions true
if (grade < 0 || grade > 10) { }          // at least one true
if (!enrolled) { }                          // inverts boolean

String comparison in if statements

Remember from the variables article: never use == to compare Strings:

String option = sc.nextLine();

// WRONG
if (option == "quit") { ... }           // may not work correctly

// CORRECT
if (option.equals("quit")) { ... }
if (option.equalsIgnoreCase("QUIT")) { ... }    // case-insensitive

// Checking for empty or null
if (option.isEmpty()) { ... }           // "" — empty string
if (option.isBlank()) { ... }           // "   " — whitespace only
if (option == null) { ... }             // null — unassigned object

The ternary operator

Identical to Python’s ternary and C’s ? ::

// Python
status = "Passed" if grade >= 5.0 else "Failed"

// Java
String status = (grade >= 5.0) ? "Passed" : "Failed";
// Useful in printf
System.out.printf("Result: %s%n", (grade >= 5.0) ? "PASS" : "FAIL");

// Nested ternary — use sparingly, can become unreadable
String classification = (grade >= 9) ? "Outstanding" :
                        (grade >= 7) ? "Merit" :
                        (grade >= 5) ? "Passed" : "Failed";

switch / case

Java’s switch is identical to C’s — same structure, same break, same fall-through behaviour, same default:

int day = 3;

switch (day) {
    case 1:
        System.out.println("Monday");
        break;
    case 2:
        System.out.println("Tuesday");
        break;
    case 3:
        System.out.println("Wednesday");
        break;
    case 4:
        System.out.println("Thursday");
        break;
    case 5:
        System.out.println("Friday");
        break;
    case 6:
    case 7:
        System.out.println("Weekend");
        break;
    default:
        System.out.println("Invalid day");
}

break is mandatory — without it execution falls through to the next case:

int x = 2;
switch (x) {
    case 1:
        System.out.println("One");
    case 2:
        System.out.println("Two");     // executes
    case 3:
        System.out.println("Three");   // also executes — no break in case 2
        break;
    case 4:
        System.out.println("Four");    // doesn't execute — break in case 3
}
// Output: Two
//         Three

Fall-through is sometimes intentional — multiple cases sharing the same action:

switch (month) {
    case 1: case 3: case 5: case 7:
    case 8: case 10: case 12:
        days = 31;
        break;
    case 4: case 6: case 9: case 11:
        days = 30;
        break;
    case 2:
        days = 28;    // simplified — ignoring leap years
        break;
}

switch works with int, char and String — not double

// int — works
switch (option) { case 1: ... }

// char — works
switch (initial) { case 'A': ... }

// String — works in Java 7+
switch (command) { case "quit": ... }

// double — does NOT work
switch (grade) { ... }    // compile error — use if/else for doubles

switch vs if/else — when to use each

Use switch when:
  → comparing one variable against exact int, char or String values
  → 3 or more distinct cases
  → values are discrete (not ranges)

Use if/else when:
  → ranges (grade >= 5.0, grade < 7.0...)
  → comparing doubles
  → conditions mixing multiple variables
  → 1 or 2 cases

A complete program

import java.util.Scanner;

public class GradeSystem {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        System.out.println("=== GRADE SYSTEM ===\n");

        /* Read input with validation */
        System.out.print("Student name: ");
        String name = sc.nextLine();

        double grade;
        System.out.print("Grade (0-10): ");
        grade = sc.nextDouble();

        /* Validate */
        if (grade < 0 || grade > 10) {
            System.out.println("Error: grade must be between 0 and 10");
            sc.close();
            return;    /* exit main — equivalent to sys.exit() */
        }

        /* Classify with if/else if */
        String classification;
        if (grade >= 9.0) {
            classification = "Outstanding";
        } else if (grade >= 7.0) {
            classification = "Merit";
        } else if (grade >= 5.0) {
            classification = "Passed";
        } else {
            classification = "Failed";
        }

        /* Status with ternary */
        String status = (grade >= 5.0) ? "PASS" : "FAIL";

        /* Output */
        System.out.println("\n--- Results ---");
        System.out.printf("Student:        %s%n", name);
        System.out.printf("Grade:          %.2f%n", grade);
        System.out.printf("Classification: %s%n", classification);
        System.out.printf("Status:         %s%n", status);

        /* Menu with switch */
        sc.nextLine();    /* consume leftover newline */
        System.out.println("\nWhat do you want to see?");
        System.out.println("A — grade as percentage");
        System.out.println("B — points to pass");
        System.out.println("C — letter grade");
        System.out.print("Option: ");
        String option = sc.nextLine().toUpperCase();

        switch (option) {
            case "A":
                System.out.printf("Percentage: %.1f%%%n", grade * 10);
                break;
            case "B":
                if (grade >= 5.0) {
                    System.out.printf("%.2f points above pass mark%n", grade - 5.0);
                } else {
                    System.out.printf("%.2f points needed to pass%n", 5.0 - grade);
                }
                break;
            case "C":
                char letter;
                if (grade >= 9.0)      letter = 'A';
                else if (grade >= 7.0) letter = 'B';
                else if (grade >= 5.0) letter = 'C';
                else                   letter = 'F';
                System.out.printf("Letter grade: %c%n", letter);
                break;
            default:
                System.out.println("Invalid option");
        }

        sc.close();
    }
}

Visualise with Python Tutor

Select Java from the dropdown and paste in pythontutor.com:

public class FlowDemo {
    public static void main(String[] args) {
        double grade = 7.5;

        String result;
        if (grade >= 9.0) {
            result = "Outstanding";
        } else if (grade >= 7.0) {
            result = "Merit";
        } else if (grade >= 5.0) {
            result = "Passed";
        } else {
            result = "Failed";
        }

        System.out.println(result);

        int option = 2;
        switch (option) {
            case 1: System.out.println("One"); break;
            case 2: System.out.println("Two"); break;
            case 3: System.out.println("Three"); break;
            default: System.out.println("Other");
        }
    }
}

Step through and observe how if/else if evaluates conditions in sequence — when grade >= 9.0 fails, Java checks grade >= 7.0, which passes with 7.5, assigns “Merit” to result and skips the remaining conditions entirely. Then watch how switch handles option = 2 — it jumps directly to case 2 without checking case 1 at all, executes the println, hits break and exits. Remove the break and step through again — you’ll see fall-through in action as execution continues into case 3 and default without checking the condition. That’s exactly what break prevents.

Quick summary

// SCANNER — read user input
import java.util.Scanner;
Scanner sc = new Scanner(System.in);

sc.nextLine()       // full line (String)
sc.nextInt()        // integer
sc.nextDouble()     // decimal
sc.next()           // one word
sc.next().charAt(0) // single character
sc.close()          // release resource

// NEXTLINE TRAP — always add after nextInt/nextDouble
sc.nextInt();
sc.nextLine();      // consume leftover newline

// IF / ELSE IF / ELSE
if (condition) {
    // ...
} else if (other_condition) {
    // ...
} else {
    // ...
}

// MANDATORY: parentheses around condition
// MANDATORY: { } around block (always — even single line)
// DIFFERENCE: elif in Python = else if in Java

// OPERATORS
// Comparison: ==  !=  >  <  >=  <=
// Logical:    &&  ||  !   (not: and or not)

// STRING COMPARISON — never ==
s1.equals(s2)
s1.equalsIgnoreCase(s2)

// TERNARY
String x = (condition) ? "value_true" : "value_false";

// SWITCH
switch (variable) {           // int, char or String — NOT double
    case value1:
        // code
        break;                // required — prevents fall-through
    case value2:
    case value3:              // multiple cases, same action
        // code
        break;
    default:
        // no match
}

// SWITCH vs IF/ELSE
// switch  → exact values, 3+ cases, int/char/String
// if/else → ranges, doubles, complex conditions

// Python → Java
// input()      → sc.nextLine()
// int(input()) → sc.nextInt()
// elif         → else if
// and/or/not   → &&/||/!
// pass         → (no equivalent — just use { })

In the next article we cover loops in Java — for, while and do-while with direct comparisons to Python and C.

Next step: practiceJava flow control practice — validator, menu and guessing game

Sigue aprendiendo

One Comment

Leave a Reply

Your email address will not be published. Required fields are marked *