SE 109 - Lecture 4: Data Types, Operators, Control Flow, and Arrays

Outline of Lecture 4

Data Types

Java data types are divided into two main groups:

Primitive Data Types Summary

TypeSize (in bits)Range / Values
byte8-128 to 127
short16-32,768 to 32,767
int32-231 to 231-1
long64-263 to 263-1
float32Approx. ±1.4e-45 to ±3.4e+38
double64Approx. ±4.9e-324 to ±1.8e+308
char160 to 65,535 (Unicode characters, e.g., 'A', '9', '\u0041')
boolean~1true or false

(Based on Slide 4 table)

The char Type

Type Conversion and Casting

Operators

Java provides a rich set of operators:

CategoryOperatorsDescription
Arithmetic+, -, *, /, %Addition, Subtraction, Multiplication, Division, Modulus (Remainder)
Unary+, -, ++, --, !Unary Plus, Unary Minus, Increment, Decrement, Logical NOT
Assignment=, +=, -=, *=, /=, %=, etc.Simple and Combined Assignment
Relational==, !=, >, <, >=, <=Equality, Inequality, Greater/Less than comparisons
Logical&&, ||Logical AND, Logical OR (Short-circuiting)
Bitwise&, |, ^, ~, <<, >>, >>>Bitwise AND, OR, XOR, Complement, Left Shift, Signed Right Shift, Unsigned Right Shift
Conditional? :Ternary Operator
Type CheckinstanceofChecks if an object is an instance of a class/interface

Bitwise Operators Example

public class Test {
    public static void main(String args[]) {
        int a = 60; /* 60 = 0011 1100 */
        int b = 13; /* 13 = 0000 1101 */
        int c = 0;

        // Bitwise AND (&)
        c = a & b; // 0011 1100 & 0000 1101 = 0000 1100 (12)
        System.out.println("a & b = " + c ); // Output: a & b = 12

        // Bitwise OR (|)
        c = a | b; // 0011 1100 | 0000 1101 = 0011 1101 (61)
        System.out.println("a | b = " + c ); // Output: a | b = 61

        // Bitwise XOR (^)
        c = a ^ b; // 0011 1100 ^ 0000 1101 = 0011 0001 (49)
        System.out.println("a ^ b = " + c ); // Output: a ^ b = 49

        // Bitwise Complement (~) - Inverts bits (affects sign due to two's complement)
        c = ~a;    // ~0011 1100 = 1100 0011 (-61 in two's complement)
        System.out.println("~a = " + c); // Output: ~a = -61

        // Left Shift (<<) - Multiplies by 2^n
        c = a << 2; // 0011 1100 << 2 = 1111 0000 (240)
        System.out.println("a << 2 = " + c); // Output: a << 2 = 240

        // Signed Right Shift (>>) - Divides by 2^n, preserves sign
        c = a >> 2; // 0011 1100 >> 2 = 0000 1111 (15)
        System.out.println("a >> 2 = " + c); // Output: a >> 2 = 15

        // Unsigned Right Shift (>>>) - Divides by 2^n, fills with 0
        c = a >>> 2; // 0011 1100 >>> 2 = 0000 1111 (15)
        System.out.println("a >>> 2 = " + c); // Output: a >>> 2 = 15
        // Difference between >> and >>> matters for negative numbers
        int neg_a = -60; // 1100 0100
        System.out.println("-60 >> 2 = " + (neg_a >> 2));   // Output: -60 >> 2 = -15 (1111 0001)
        System.out.println("-60 >>> 2 = " + (neg_a >>> 2)); // Output: -60 >>> 2 = 1073741809 (0011 1100 01...) - fills with 0s
    }
}

Combined Assignment Operators Example

public class MainClass {
    public static void main(String args[]) {
        int a = 1, b = 2, c = 3;

        a += 5; // a = a + 5 --> a becomes 6
        b *= 4; // b = b * 4 --> b becomes 8
        // c += a * b; is equivalent to c = c + (a * b)
        c += a * b; // c = 3 + (6 * 8) = 3 + 48 = 51
        c %= 6; // c = c % 6 --> c = 51 % 6 = 3 (remainder of 51/6)

        System.out.println("a = " + a); // Output: a = 6
        System.out.println("b = " + b); // Output: b = 8
        System.out.println("c = " + c); // Output: c = 3
    }
}

Conditional (Ternary) Operator (? :)

A shorthand for an if-else statement that produces a value.

Syntax: condition ? value_if_true : value_if_false

It evaluates the condition. If true, the entire expression evaluates to value_if_true; otherwise, it evaluates to value_if_false.

Often used in assignments or return statements.

public class Test {
    public static void main(String args[]){
        int a = 10, b;
        int x = 5, y = 10;

        b = (a == 1) ? 20 : 30; // a is 10, condition is false, b becomes 30
        System.out.println( "Value of b is : " + b ); // Output: Value of b is : 30

        b = (a == 10) ? 20 : 30; // a is 10, condition is true, b becomes 20
        System.out.println( "Value of b is : " + b ); // Output: Value of b is : 20

        // Example from slide 18
        int larger = (x >= y) ? x : y; // x=5, y=10. Condition false. larger becomes y (10).
        System.out.println("Larger is: " + larger); // Output: Larger is: 10

        // Example from slide 18
        int n = -5;
        int absValue = (n < 0) ? -n : n; // n=-5. Condition true. absValue becomes -(-5) = 5.
        System.out.println("Absolute value is: " + absValue); // Output: Absolute value is: 5
    }
}

instanceof Operator

Checks if an object is an instance of a particular class or implements a specific interface.

Syntax: objectReference instanceof Type

Returns true if the object referred to by objectReference is of type Type (or a subclass of Type, or implements Type if it's an interface), otherwise returns false.

public class Test {
    public static void main(String args[]){
        String name = "James";
        Integer number = 10;

        // following will return true since name is type of String
        boolean result1 = name instanceof String;
        System.out.println( "name instanceof String: " + result1 ); // Output: name instanceof String: true

        boolean result2 = name instanceof Object; // All classes inherit from Object
        System.out.println( "name instanceof Object: " + result2 ); // Output: name instanceof Object: true

        // boolean result3 = number instanceof String; // Compile error: Incompatible types
        // System.out.println( "number instanceof String: " + result3 );

         boolean result4 = number instanceof Integer;
         System.out.println( "number instanceof Integer: " + result4 ); // Output: number instanceof Integer: true

         Object obj = name; // Assign String to Object reference
         boolean result5 = obj instanceof String;
         System.out.println( "obj instanceof String: " + result5 ); // Output: obj instanceof String: true

         obj = number; // Assign Integer to Object reference
         boolean result6 = obj instanceof Integer;
         System.out.println( "obj instanceof Integer: " + result6 ); // Output: obj instanceof Integer: true
    }
}

Operator Precedence

Determines the order in which operators are evaluated in an expression. Parentheses () can override precedence.

(Slide 15 showed a detailed precedence table. Key general rules: Unary ops > Multiplicative > Additive > Relational > Equality > Logical AND > Logical OR > Conditional > Assignment).

CategoryOperatorAssociativity
Postfixexpr++ expr--Left to right
Unary++expr --expr +expr -expr ~ !Right to left
Multiplicative* / %Left to right
Additive+ -Left to right
Shift<< >> >>>Left to right
Relational< > <= >= instanceofLeft to right
Equality== !=Left to right
Bitwise AND&Left to right
Bitwise XOR^Left to right
Bitwise OR|Left to right
Logical AND&&Left to right
Logical OR||Left to right
Conditional? :Right to left
Assignment= += -= *= /= %= &= ^= |= <<= >>= >>>=Right to left

Operators on the same line generally have equal precedence and are evaluated based on associativity (usually left-to-right, except for unary and assignment).

String Handling

String is a non-primitive data type (a class) in Java, found in the java.lang package (automatically available).

(Slides 19-24 illustrated String pool behavior, heap allocation with `new`, and the difference between literal and `new` instantiation regarding references. Slides 26-28 showed `==` vs `.equals()` comparison examples).

String Comparison Example:

String s1 = "Hello";       // From pool
String s2 = "Hello";       // From pool (same object as s1)
String s3 = new String("Hello"); // New object on heap
String s4 = new String("Hello"); // Another new object on heap
String s5 = "He" + "llo";  // Concatenated literal, resolves to "Hello", from pool (same as s1)

System.out.println("s1 == s2: " + (s1 == s2)); // true (both point to same pool object)
System.out.println("s1 == s3: " + (s1 == s3)); // false (different objects)
System.out.println("s3 == s4: " + (s3 == s4)); // false (different objects on heap)
System.out.println("s1 == s5: " + (s1 == s5)); // true (s5 resolves to the same pool object)

System.out.println("s1.equals(s2): " + s1.equals(s2)); // true (content matches)
System.out.println("s1.equals(s3): " + s1.equals(s3)); // true (content matches)
System.out.println("s3.equals(s4): " + s3.equals(s4)); // true (content matches)
System.out.println("s1.equals(s5): " + s1.equals(s5)); // true (content matches)

Selection Statements (Conditional Control Flow)

Allow the program to choose between different paths of execution based on a condition (a boolean expression).

if Statement

Executes a block of code only if a condition is true.

Syntax:

if (condition) {
    // Statement(s) to execute if condition is true
}
// or for a single statement:
if (condition)
    statement; // Executes if condition is true

Flow: If condition is true, execute statement(s) inside the block/following the if. Then continue after the block. If condition is false, skip the statement(s) and continue after the block.

(Slide 36 illustrated this flow: A -> if(true) -> B -> C; A -> if(false) -> C).

if-else Statement

Executes one block of code if a condition is true, and another block if the condition is false.

Syntax:

if (condition) {
    // Statement(s) to execute if condition is true
} else {
    // Statement(s) to execute if condition is false
}

Flow: If condition is true, execute the `if` block, then skip the `else` block and continue after it. If condition is false, skip the `if` block, execute the `else` block, and then continue after it. Only one of the blocks (if or else) is ever executed.

(Slides 4 & 5 from the second deck, and 41 & 42 from the first deck, illustrated this flow: A -> if(true) -> B -> D; A -> if(false) -> C -> D. Statements B and C are mutually exclusive).

Example: Odd or Even

import java.util.Scanner;

public class TestInputOddorEven {
    public static void main(String[] args) {
        System.out.println("Please type an integer");
        Scanner sc = new Scanner(System.in);
        int x = sc.nextInt();

        // Check if the remainder when divided by 2 is not 0
        if ((x % 2) != 0) {
            System.out.println(x + " is odd");
        } else {
            System.out.println(x + " is even");
        }
         sc.close(); // Good practice to close scanner
    }
}

Example: Compare Two Integers

import java.util.Scanner;

public class TestInput {
    public static void main(String[] args) {
        System.out.println("Please type two integers.");
        Scanner sc = new Scanner(System.in);
        int x = sc.nextInt();
        int y = sc.nextInt();

        if (x >= y) {
            System.out.println(x + " is the larger or they are equal.");
        } else {
            System.out.println(y + " is the larger.");
        }
         sc.close();
    }
}

Nested if Statements

An if or if-else statement can be placed inside another if or else block.

Example: Find Largest of Three Numbers

// Assuming x, y, z are integers and largest is an int variable
if (x >= y) {
    // x is potentially the largest
    if (x >= z) {
        largest = x;
    } else { // x < z, and x >= y --> z is largest
        largest = z;
    }
} else { // x < y, so y is potentially the largest (or z)
    if (y >= z) {
        largest = y;
    } else { // y < z, and y > x --> z is largest
        largest = z;
    }
}
System.out.println("The largest number is: " + largest);

Cascading if-else if Statement

Used to select one block of code to execute from multiple alternatives based on a series of conditions.

Syntax:

if (condition1) {
    // Execute if condition1 is true
} else if (condition2) {
    // Execute if condition1 is false AND condition2 is true
} else if (condition3) {
    // Execute if condition1 AND condition2 are false, AND condition3 is true
} else {
    // Optional: Execute if none of the preceding conditions are true
}

The conditions are checked in order. As soon as one condition evaluates to true, its corresponding block is executed, and the rest of the chain is skipped.

Example: Simple Calculator

public class CalcClass {
    public static void main(String[] arg) {
        int a = 10, b = 3; // Changed values for clarity
        char op = '+'; // Example operator

        if (op == '+') {
            System.out.println("sum is " + (a + b)); // Output: sum is 13
        } else if (op == '-') {
            System.out.println("sub is " + (a - b));
        } else if (op == '*') {
            System.out.println("mul is " + (a * b));
        } else if (op == '/') {
             if (b != 0) { // Avoid division by zero
                System.out.println("div is " + (a / b)); // Integer division
             } else {
                 System.out.println("Cannot divide by zero");
             }
        } else {
            System.out.println("Invalid operator");
        }
    }
}

Multi-Expression Conditions (Logical Operators)

Combine multiple boolean expressions using logical operators (&&, ||, !).

OperatorLHSRHSResultNotes
&& (AND)falseanyfalseShort-circuit: RHS not evaluated if LHS is false.
&& (AND)truefalsefalse
&& (AND)truetruetrueResult is true only if BOTH operands are true.
|| (OR)trueanytrueShort-circuit: RHS not evaluated if LHS is true.
|| (OR)falsefalsefalseResult is false only if BOTH operands are false.
|| (OR)falsetruetrue
! (NOT)trueN/AfalseReverses the boolean value.
! (NOT)falseN/Atrue

Note: Java also has non-short-circuit bitwise logical operators (&, |) which *always* evaluate both operands, but these are less commonly used for boolean logic control flow.

int x = 5, y = 5, z = 5;
int a = -1, b = -2;

// Logical AND Example
if ((x == y) && (y == z)) { // true && true --> true
    System.out.println("x, y and z are equal."); // This will print
}

if ((a < 0) && (b < 0)) { // true && true --> true
    System.out.println("Both values are negative."); // This will print
}

// Logical OR Example
x = 3; // Change x
if ((x < y) || (x < z)) { // 3 < 5 (true) || (doesn't matter) --> true
    System.out.println("x is not the largest."); // This will print
}

a = 10; // Change a
if ((a < 0) || (b < 0)) { // false || true --> true
    System.out.println("At least one is negative."); // This will print
}

// Logical NOT Example
boolean isOverdrawn = false;
if (!isOverdrawn) { // !false --> true
    System.out.println("Account is not overdrawn. Permit debit."); // This will print
}

switch Statement

An alternative to a series of if-else if statements, particularly useful when checking a single variable against multiple constant values.

Syntax:

switch (expression) {
    case value1:
        // Code block for value1
        break; // Exits the switch
    case value2:
        // Code block for value2
        break;
    case value3: // Example of fall-through
    case value4:
        // Code block for value3 OR value4
        break;
    default: // Optional
        // Code block if no case matches
        // break; // Optional here, as it's the last block
}

Example: Day of the week (with fall-through)

public class Main {
    public static void main(String[] args) {
        int day = 2; // Example: Tuesday

        switch (day) {
            case 1:
                System.out.println("Monday");
                break;
            case 2:
                System.out.println("Tuesday");
                // No break here - deliberate fall-through!
            case 3:
                System.out.println("Wednesday");
                break; // Exits after printing Wednesday
            case 4:
                System.out.println("Thursday");
                break;
            case 5:
                System.out.println("Friday");
                break;
            default:
                System.out.println("Weekend or Invalid day");
        }
        // Output for day = 2:
        // Tuesday
        // Wednesday
    }
}

Example: Character Switch

public class MainClass {
    public static void main(String[] args) {
        char i = '2'; // Example input

        switch (i) {
            case '1':
                System.out.println("One.");
                break;
            case '2':
                System.out.println("Two."); // This will print
                break; // Exits
            case '3':
                System.out.println("Three.");
                break;
            default:
                System.out.println("You did not enter a valid value (1, 2, or 3).");
        }
        // Output: Two.
    }
}

Example: Default Position (Default doesn't have to be last, but break is important)

public class Main {
    public static void main(String[] args) {
        int day = 4; // Example: Thursday

        switch (day) {
            default: // Default can appear anywhere, but execution continues if no break
                System.out.println("Looking forward to the Weekend");
                // break; // <-- If break was here, only this would print for day=4

            case 6:
                System.out.println("Today is Saturday");
                break;
            case 7:
                System.out.println("Today is Sunday");
                break;
        }
        // Output for day = 4:
        // Looking forward to the Weekend
        // Today is Saturday
    }
}

Repetition Statements (Loops)

Used to execute a block of code repeatedly as long as a condition is met or for a specific number of times.

1. for Loop

Ideal when the number of iterations is known beforehand.

Syntax:

for (initialization; condition; update) {
    // Statement(s) to execute in each iteration
}

You can have multiple initializations or updates, separated by commas.

Example: Print Squares 0-9

// Example from Slide 3
for (int i = 0; i < 10; i++) { // i is local to this loop
    System.out.println(i + " squared is " + (i * i));
}
// 'i' cannot be accessed here

Output:

0 squared is 0
1 squared is 1
2 squared is 4
3 squared is 9
4 squared is 16
5 squared is 25
6 squared is 36
7 squared is 49
8 squared is 64
9 squared is 81

Example: Multiple Variables

// Example from Slide 4
for (int i = 0, j = 10; i < 10; i++, j--) { // i increments, j decrements
    System.out.println(i + " " + j);
    // Variables i and j are local to this loop
}

Output:

0 10
1 9
2 8
3 7
4 6
5 5
6 4
7 3
8 2
9 1

1a. Enhanced for Loop (for-each)

Provides a simpler way to iterate through all elements of an array or a collection without using an index explicitly.

Syntax:

for (DataType elementVariable : arrayOrCollection) {
    // Statement(s) using elementVariable
}

Example: Print Elements of a String Array

String[] names = {"Alice", "Bob", "Charlie"};

System.out.println("Names in the array:");
for (String name : names) { // For each String 'name' in the 'names' array
    System.out.println(name);
}

Output:

Names in the array:
Alice
Bob
Charlie

Example: Iterating Over a 2D Array

int[][] myNumbers = { {1, 2, 3, 4}, {5, 6, 7} };

System.out.println("Numbers in the 2D array:");
// Outer loop iterates through each row (which is an int[] array)
for (int[] row : myNumbers) {
    // Inner loop iterates through each integer 'i' in the current 'row'
    for (int i : row) {
        System.out.println(i);
    }
}

Output:

Numbers in the 2D array:
1
2
3
4
5
6
7

2. while Loop

Executes a block of code repeatedly *as long as* a condition remains true. The condition is checked *before* each iteration. If the condition is initially false, the loop body never executes.

Syntax:

initialization; // Initialize loop variable(s) before the loop
while (condition) {
    // Statement(s) to execute
    update; // Update loop variable(s) inside the loop
}

Example: Print Squares 0-9

// Example from Slide 5
int i = 0; // Initialization
while (i < 10) { // Condition
    System.out.println(i + " squared is " + (i * i));
    i++; // Update
}

(Output is the same as the `for` loop example above).

3. do-while Loop

Similar to `while`, but the condition is checked *after* the loop body executes. This guarantees the loop body runs at least once, even if the condition is initially false.

Syntax:

initialization;
do {
    // Statement(s) to execute
    update;
} while (condition); // Note the semicolon at the end

Example: Print Squares 0-9

// Example from Slide 6
int i = 0; // Initialization
do {
    System.out.println(i + " squared is " + (i * i));
    i++; // Update
} while (i < 10); // Condition checked after the first iteration

(Output is the same as the `for` and `while` loop examples above).

When to use which loop?

Loop Control Statements: break and continue

Example: Using break

// Example from Slide 8
public class Main {
    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            if (i == 4) {
                break; // Exit the loop when i is 4
            }
            System.out.println(i);
        }
        // Output after loop: (Loop exited when i was 4)
        System.out.println("Loop finished.");
    }
}

Output:

0
1
2
3
Loop finished.

Example: Using continue

// Example from Slide 9
public class Main {
    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            if (i == 4) {
                continue; // Skip the rest of this iteration when i is 4
            }
            System.out.println(i); // This line is skipped when i is 4
        }
         System.out.println("Loop finished.");
   }
}

Output:

0
1
2
3
5
6
7
8
9
Loop finished.

Nested Loops

Placing one loop inside another loop.

The "inner loop" completes all its iterations for *each single* iteration of the "outer loop".

Example: Outer/Inner Loop Execution

// Example from Slide 10
// Outer loop
for (int i = 1; i <= 2; i++) {
    System.out.println("Outer: " + i); // Executes 2 times

    // Inner loop
    for (int j = 1; j <= 3; j++) {
        System.out.println(" Inner: " + j); // Executes 3 times for each outer loop iteration (6 times total)
    }
}

Output:

Outer: 1
 Inner: 1
 Inner: 2
 Inner: 3
Outer: 2
 Inner: 1
 Inner: 2
 Inner: 3

Nested Loops for Patterns

Nested loops are commonly used to print patterns.

(Slides 11 & 12 showed images of various star and number patterns achievable with nested loops).

Example: Simple Triangle Pattern

// Based on Slide 13 (corrected System.out.println usage)
public class Main {
    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) { // Outer loop controls rows
            // Inner loop controls columns in the current row
            for (int j = 0; j <= i; j++) { // Prints '*' j times, up to i
                System.out.print("*"); // print() stays on the same line
            }
            System.out.println(); // Moves to the next line after inner loop finishes
        }
    }
}

Output:

*
**
***
****
*****

Arrays

Arrays are used to store multiple values of the same type in a single variable.

Instead of declaring many variables like int x1, x2, ..., x50;, you can use an array: int[] x = new int[50];.

Declaring Arrays

You declare an array variable by specifying the type followed by square brackets [] and the variable name.

dataType[] arrayName; // Preferred way
// or
dataType arrayName[]; // Works, but less common (C/C++ style)

Examples:

Note: Declaring an array variable only creates a reference; it does not create the actual array object in memory yet.

Creating (Instantiating) Arrays

You create the array object and allocate memory using the new keyword, specifying the type and size.

arrayName = new dataType[size];

Examples:

When an array is created using new, its elements are initialized to default values:

The new operator determines the size, and once created, the array's size cannot be changed.

The array variable (e.g., myNum, s, cars) holds a reference to the first element (or the array object itself) in memory.

Initializing Arrays

You can declare, create, and initialize an array in one step using an array initializer (curly braces {}).

dataType[] arrayName = {value1, value2, value3, ...};

The size is implicitly determined by the number of elements provided.

Example:

String[] cars = {"Volvo", "BMW", "Ford", "Mazda"}; // Size is 4
int[] numbers = {10, 20, 30, 40, 50}; // Size is 5
char[] letters = {'a', 'b', 'c'}; // Size is 3

Accessing Array Elements

Elements are accessed using their zero-based index inside square brackets [].

arrayName[index]

Examples:

Valid indices range from 0 to arrayName.length - 1. Accessing an index outside this range will cause an ArrayIndexOutOfBoundsException at runtime.

Array Length

The number of elements in an array can be found using its length property (it's a property, not a method, so no parentheses).

int size = cars.length; // size would be 4 for the cars array above

Iterating Through Arrays

A common way to process all elements in an array is using a for loop with the length property.

Example: Print all cars

String[] cars = {"Volvo", "BMW", "Ford", "Mazda"};

// Using a standard for loop
System.out.println("Using standard for loop:");
for (int i = 0; i < cars.length; i++) {
    System.out.println(cars[i]);
}

// Using an enhanced for loop (for-each loop) - simpler syntax
System.out.println("\nUsing enhanced for loop:");
for (String car : cars) { // For each String 'car' in the 'cars' array
    System.out.println(car);
}

Output (for both loops):

Volvo
BMW
Ford
Mazda

Arrays Example: Creating and Returning an Array

Example: Method to create an array of characters A-Z

public class ArrayExample {

    // This method creates and returns an array of characters 'A' through 'Z'
    public static char[] createAlphabetArray() {
        // Declare a reference variable 's' for a char array
        char[] s;

        // Create the char array object with size 26
        // and assign its reference to 's'
        s = new char[26]; // Elements initialized to '\u0000'

        // Alternative: Initialize with literals (but not A-Z easily)
        // char[] s = {'a', 'b', 'c', ... };

        // Fill the array with characters 'A' through 'Z'
        for (int i = 0; i < 26; i++) {
            // 'A' has an ASCII/Unicode value. Adding 'i' gives subsequent values.
            // The result of ('A' + i) is an int, so it must be cast back to char.
            s[i] = (char) ('A' + i);
        }
        return s; // Return the reference to the created array
    }

    public static void main(String[] args) {
        char[] alphabet = createAlphabetArray(); // Call the method

        // Print the returned array
        System.out.println("Created Alphabet Array:");
        for (int i = 0; i < alphabet.length; i++) {
            System.out.print(alphabet[i] + " ");
        }
        System.out.println();
        // Output: A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
    }
}

Notes:

Exercises (From Slide 21)

  1. Create a program that prints a star pattern (like a pyramid or triangle) using nested loops. (See Slide 13 for a basic example).
  2. Create a program that implements the factorial function (e.g., calculates 5! = 5 * 4 * 3 * 2 * 1). You could use a loop for this.

(Solutions for these exercises are not provided in the slides but are common programming tasks using loops).