An Overview of Java: Object-Oriented Programming (Two Paradigms,
Abstraction, The Three OOP Principles), Using Blocks of Code, Lexical Issues (Whitespace, Identifiers, Literals, Comments, Separators, The Java Keywords). Data Types, Variables, and Arrays: The Primitive Types (Integers, Floating-Point Types, Characters, Booleans), Variables, Type Conversion and Casting, Automatic Type Promotion in Expressions, Arrays, Introducing Type Inference with Local Variables. Operators: Arithmetic Operators, Relational Operators, Boolean Logical Operators, The Assignment Operator, The ? Operator, Operator Precedence, Using Parentheses. Control Statements: Java’s Selection Statements (if, The Traditional switch), Iteration Statements (while, do-while, for, The For-Each Version of the for Loop, Local Variable Type Inference in a for Loop, Nested Loops), Jump Statements (Using break, Using continue, return). Object-Oriented Programming • Object-Oriented Programming (OOP) is a fundamental concept that underlies the design and structure of Java programs. • Java is built around the principles of OOP, which makes it a powerful and flexible language for creating complex and reusable code. • Two Paradigms • All computer programs consist of two elements: code and data. • A program can be conceptually organized around its code or around its data • Computer programming paradigms are approaches or styles of programming that offer different ways to solve problems and structure code. • Two primary paradigms are: 1.Procedural Programming 2.Object-Oriented Programming (OOP) 1. Procedural Programming Procedural programming is a paradigm derived from structured programming, emphasizing a sequence of computational steps to be carried out. It focuses on the concept of procedure calls, where statements are structured into procedures (also known as functions or subroutines). Key Characteristics: • Modularity: Code is organized into procedures or functions, making it modular. • Sequential Execution: Execution of statements in a specific order. • State Management: Utilizes variables to store state information. 2. Object-Oriented Programming (OOP) Object-Oriented Programming (OOP) is a paradigm based on the concept of "objects", which are instances of classes. It combines data and the operations that manipulate the data into a single unit called an object. OOP aims to increase the flexibility and maintainability of code. Key Characteristics: • Encapsulation: Bundling of data (attributes) and methods (functions) that operate on the data into a single unit (class). • Inheritance: Mechanism to create a new class using properties and methods of an existing class. • Polymorphism: Ability to process objects differently based on their class. • Abstraction: Hiding the complex implementation details and showing only the necessary features of an object. Abstraction • Abstraction is a fundamental element of object-oriented programming, allowing humans to manage complexity by thinking of complex systems as single, well-defined objects with unique behaviors, rather than as collections of individual parts. • Abstraction in Java is a key concept in object-oriented programming (OOP) that focuses on hiding the complex implementation details and exposing only the necessary features of an object. • This helps in managing complexity by reducing what the user needs to know about an object to use it effectively. • Java provides two main ways to achieve abstraction: through abstract classes and interfaces. The Three OOP Principles The three core principles of Object-Oriented Programming (OOP) are Encapsulation, Inheritance, and Polymorphism. These principles help in creating modular, reusable, and maintainable code. 1. Encapsulation Encapsulation involves bundling the data (attributes) and the methods (functions) that operate on the data into a single unit called a class. It restricts direct access to some of an object's components, which can prevent the accidental modification of data. Key Points: • Data Hiding: Internal state of the object is hidden from the outside; only accessible through public methods. • Modularization: Code is organized into discrete units (classes) that are easy to manage and understand. 2. Inheritance Inheritance is a mechanism where a new class (subclass) inherits properties and behaviors (methods) from an existing class (superclass). It promotes code reusability and establishes a natural hierarchy between classes. Key Points: • Code Reusability: Common functionality is defined in a base class, which can be extended by subclasses. • Hierarchy: Creates a relationship between a more general superclass and more specific subclasses. 3. Polymorphism Polymorphism allows objects of different classes to be treated as objects of a common super class. It enables a single interface to represent different underlying data types. There are two types of polymorphism in Java: compile-time (method overloading) and runtime (method overriding). Key Points: • Method Overloading (Compile-time Polymorphism): Multiple methods with the same name but different parameters. • Method Overriding (Runtime Polymorphism): Subclass provides a specific implementation of a method that is already defined in its superclass. A First Simple Program public class First { public static void main(String[] args) { System.out.println("Hello, World!"); } } Writing Java Code Using a Text Editor: • Open a new file in your text editor. • Type your Java code in the file. • Save the file with First.java extension Compiling and Running Java Code: Use the javac command to compile your Java file. This will generate a First.class file. Use the java command to run the compiled class. You should see the output: Hello, World! Using Blocks of Code • Java allows two or more statements to be grouped into blocks of code, also called code blocks. • This is done by enclosing the statements between opening and closing curly braces. • Once a block of code has been created, it becomes a logical unit that can be used any place that a single statement can. • For example, a block can be a target for Java’s if and for statements. • Consider this if statement: if (x<y) { x=y; y=0; } • Here, if x is less than y, then both statements inside the block will be executed. • Thus, the two statements inside the block form a logical unit, and one statement cannot execute without the other also executing. • whenever you need to logically link two or more statements, you do so by creating a block. Lexical Issues Java programs are a collection of whitespace, identifiers, literals, comments, operators, separators, and keywords. Whitespace: • Java is a free-form language. • This means that you do not need to follow any special indentation rules. • For example; you can type all the code of a java program in one line as long as there is at least one whitespace character between each token that is not already delineated by an operator or separator. • In Java, whitespace includes a space, tab, newline, or form feed. Identifiers • Identifiers are names given to elements such as classes, methods, variables, and other user-defined items. • They are essential for identifying these elements within the program. Rules for Identifiers 1. Must start with a letter (a-z, A-Z), a dollar sign ($), or an underscore (_). 2. Subsequent characters can be letters, digits (0-9), dollar signs, or underscores. 3. Case sensitivity: Myvariable and myvariable are different identifiers. 4. There is no specific limit on the length of an identifier, but it should be concise and meaningful. 5. Identifiers cannot be the same as Java reserved keywords 6. Identifiers cannot contain spaces or special characters ( like @,#,% etc) except for the dollar sign and underscore. Literals In Java, literals are fixed values that are explicitly defined in the code. They represent constant values and can be assigned to variables or used directly in expressions. Java supports several types of literals, categorized based on the data type they represent. Here’s the different types of literals in Java: • Integer Literals • Floating-Point Literals • Character Literals • String Literals • Boolean Literals • Null Literal Comments • In Java, comments are used to annotate code, providing explanations or notes that help others (or yourself) understand the code's purpose and functionality. • Comments are ignored by the Java compiler, meaning they do not affect the program's execution. • There are three types of comments in Java: 1. Single-line comments begin with two forward slashes (//) 2. Multi-line comments begin with /* and end with */ 3. Documentation comments, also known as Javadoc comments, are a specific type of multi-line comment that starts with /** and ends with */ Separators • In Java, separators are special characters used to organize and separate different components of the code. • They play a crucial role in defining the structure and syntax of Java programs Separators The java keywords • In Java, keywords are reserved words that have predefined meanings in the language. • They cannot be used as identifiers (e.g., names for variables, classes, or methods). • Java keywords help define the structure of the program and dictate how the code behaves • Here’s a comprehensive list of Java keywords The Primitive Types • In Java, primitive types are the most basic data types. • They are not objects and hold their values directly in memory. • Java has eight primitive types, which can be categorized into four main groups: integers, floating-point types, characters, and Booleans 1. Integer Types • These types represent whole numbers without any fractional component. • Java provides four integer types: byte, short, int and long 2. Floating-Point Types • These types represent numbers with a fractional component. • Java provides two floating-point types: float and double 3. Character Type • The character type in Java represents a single 16-bit Unicode character. (char) 4. Boolean Type • The boolean type represents a truth value, indicating whether a condition is true or false. Summary of Primitive Types Variables • The variable is the basic unit of storage in a Java program. A • variable is defined by the combination of an identifier, a type, and an optional initializer. • In addition, all variables have a scope, which defines their visibility, and a lifetime. Declaring a Variable • In Java, all variables must be declared before they can be used. • The basic form of a variable declaration is : type identifier [ = value][, identifier [= value] ...] ; • The type is one of Java’s atomic types, or the name of a class or interface. • The identifier is the name of the variable. • You can initialize the variable by specifying an equal sign and a value. • To declare more than one variable of the specified type, use a comma separated list. • Examples of variable declarations of various types: int a, b, c; int d = 3, e, f = 5; byte z = 22;. double pi = 3.14159; char x = 'x'; Dynamic Initialization • Java allows variables to be initialized dynamically, using any expression valid at the time the variable is declared. • Consider the program below class DynInit { public static void main(String args[]) { double a = 3.0, b = 4.0; double c = Math.sqrt(a * a + b * b); // c is dynamically initialized System.out.println("Hypotenuse is " + c); } } • Here, three local variables—a, b, and c—are declared. • The first two, a and b, are initialized by constants. • c is initialized dynamically to the length of the hypotenuse The Scope and Lifetime of Variables • The scope and lifetime of variables in Java are fundamental concepts that determine where and how long a variable can be accessed within a program • Scope of Variables: Scope refers to the region in the program where a variable is accessible. • Java defines several scopes based on where variables are declared: Local Scope • Definition: Variables declared inside a method, constructor, or block (such as loops or conditionals). • Access: Accessible only within the method, constructor, or block where they are declared. Instance Scope • Definition: Instance variables are declared within a class but outside any method or constructor. • Access: Accessible to all instance methods within the class. Each object of the class has its own copy of instance variables. Static Scope • Definition: Static variables are declared with the static keyword within a class. • Access: Accessible from all instance methods and static methods within the class, and can also be accessed from outside the class using the class name. Block Scope • Definition: Variables declared within a specific block (enclosed in {} such as in loops or conditional statements. • Access: Accessible only within that block. Type Conversion and Casting In Java, type conversion and casting are essential concepts that deal with converting one data type into another. This is particularly important in a statically typed language like Java, where variable types must be known at compile time. 1. Type Conversion • Type conversion in Java refers to the process of converting one data type into another. There are two main types of type conversion: a. Widening Conversion (Implicit Conversion) Definition: Widening conversion happens when you convert a smaller data type into a larger data type. This is done automatically by the Java compiler, as there is no risk of data loss. Examples of Widening Conversion: byte to short short to int int to long float to double b. Narrowing Conversion (Explicit Conversion) Definition: Narrowing conversion occurs when you convert a larger data type into a smaller data type. This must be done explicitly because it can lead to data loss (e.g., converting double to int) Examples of Narrowing Conversion: double to float float to int int to short long to int 2. Type Casting Type casting is the process of converting a variable from one type to another. In Java, type casting is usually associated with narrowing conversions, where explicit casting is required. There are two types of casting: a. Casting Primitive Types primitive types can be cast explicitly using parentheses. b. Casting Reference Types • When dealing with objects, casting is used to convert an object of one type to another type within the same hierarchy. There are two types of reference casting: • Upcasting: Casting a subclass object to a superclass reference. This is done implicitly and safe because the subclass is guaranteed to be an instance of the superclass. • Downcasting: Casting a superclass reference back to a subclass reference. This must be done explicitly and can result in a ClassCastException if the object being cast is not an instance of the subclass. Automatic Type Promotion in Expressions Automatic type promotion in expressions is a feature in Java that allows the conversion of smaller data types to larger data types during operations involving mixed data types. This ensures that calculations are performed with compatible types, minimizing the risk of data loss or overflow. Basic Rules of Automatic Type Promotion When performing operations involving different primitive types, Java applies the following promotion rules: Promotion Hierarchy: Java promotes smaller types to larger types based on their size and precision. The promotion order is as follows: byte, short and char are promoted to int int is promoted to long long is promoted to float float is promoted to double Operations Involving Mixed Types: If an expression contains two different types, Java will automatically promote the smaller type to the larger type to ensure the operation is performed without loss of information. Arrays • An array is a group of like-typed variables that are referred to by a common name. • Arrays of any type can be created and may have one or more dimensions. • A specific element in an array is accessed by its index. • Arrays offer a convenient means of grouping related information. One-Dimensional Arrays • A one-dimensional array is a list of like-typed variables. • To create an array, you first must create an array variable of the desired type. • The general form of a one-dimensional array declaration is: type var-name[ ]; • Here, type declares the base type of the array. • The base type determines the data type of each element that comprises the array. ie, the base type for the array determines what type of data the array will hold. • For example: int month_days[]; • After declaring an array, we must allocate memory using the new operator. • new is a special operator that allocates memory. • The general form of new is: array-var = new type[size]; • Here, type specifies the type of data being allocated, size specifies the number of elements in the array, and array-var is the array variable that is linked to the array. • For example: month_days = new int[12]; • Obtaining an array is a two-step process. • First, you must declare a variable of the desired array type. • Second, you must allocate the memory that will hold the array, using new, and assign it to the array variable. • In Java all arrays are dynamically allocated. • Once you have allocated an array, you can access a specific element in the array by specifying its index within square brackets. • All array indexes start at zero. • For example, this statement assigns the value 28 to the second element of month_days. month_days[1] = 28; • To displays the value stored at index 3, you can use the following statement: System.out.println(month_days[3]); • It is possible to combine the declaration of the array variable with the allocation of the array itself, int month_days[] = new int[12]; • Arrays can be initialized when they are declared. • An array initializer is a list of comma-separated expressions surrounded by curly braces. • The commas separate the values of the array elements. • The array will automatically be created large enough to hold the number of elements you specify in the array initializer. There is no need to use new. • For example: int month_days[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; Multidimensional Arrays • In Java, multidimensional arrays are actually arrays of arrays. • To declare a multidimensional array variable, specify each additional index using another set of square brackets. • For example, the following declares a two dimensional array variable called twoD. int twoD[][] = new int[4][5]; • This allocates a 4 by 5 array and assigns it to twoD. • Internally this matrix is implemented as an array of arrays of int. • Conceptually, this array will look like the figure below: Introducing Type Inference with Local Variables • In Java, type inference with local variables was introduced in Java 10 through the use of the var keyword. • This feature allows the compiler to infer the type of the local variable based on the type of the initializer, making the code more concise and readable while still being statically typed. Key Features of Type Inference with var • Simplifies Code: Reduces verbosity by eliminating the need to explicitly declare the type of the variable when it can be inferred from the context. • Maintains Static Typing: Despite using var the variables are still statically typed. The type is determined at compile time and cannot be changed later. • Improves Readability: Can make code more readable by removing redundant type information, especially when the type is obvious from the context. Usage of var • Local Variables: var can be used to declare local variables with an initializer. • For-Each Loop Variables: var can be used in enhanced for-loops. • Index Variables in For-Loops: var can be used to declare index variables in traditional for-loops. • Try-With-Resources: var can be used to declare resources in try-with-resources statements. Operators • Operators in Java are special symbols or keywords that perform operations on one or more operands. • Java provides a rich set of operators to manipulate variables and perform various computations. Arithmetic Operators • Arithmetic operators are used to perform basic mathematical operations such as addition, subtraction, multiplication, division, and modulus. • The operands of the arithmetic operators must be of a numeric type. • You cannot use them on boolean types, but you can use them on char types, since the char type in Java is, essentially, a subset of int. The Basic Arithmetic Operators —addition, subtraction, multiplication, and division— • The minus operator also has a unary form that negates its single operand. • when the division operator is applied to an integer type, there will be no fractional component attached to the result. • The modulus operator, %, returns the remainder of a division operation. It can be applied to floating-point types as well as integer types. The list arithmetic operators in java Arithmetic Compound Assignment Operators • Java provides special operators that can be used to combine an arithmetic operation with an assignment • The following are compound assignment operators: +=, -=, *=, /= and %= • For example, consider the statement a = a + 4; can rewrite this statement: a += 4; Increment and Decrement The ++ and the – – are Java’s increment and decrement operators. • The increment operator increases its operand by one. The decrement operator decreases its operand by one. For example, this statement: x = x + 1; can be rewritten like this by use of the increment operator: x++; • Similarly, this statement: x = x - 1; is equivalent to x--; • These operators are unique in that they can appear both in postfix form, and prefix form. • There is no difference between the prefix and postfix forms. • However, when the increment and/or decrement operators are part of a larger expression, then there is a difference between these two forms. • In the prefix form, the operand is incremented or decremented before the value is obtained for use in the expression. • In postfix form, the previous value is obtained for use in the expression, and then the operand is modified. Relational Operators • Relational operators in Java are used to compare two values. • These operators return a boolean value (true or false) based on the comparison. • The relational operators are most frequently used in the expressions that control the if statement and the various loop statements. • Any type including integers, floating-point numbers, characters, and Booleans can be compared using the equality operator, ==, and the inequality operator !=. • Only numeric types can be compared using the ordering operators. • The relational operators are Boolean Logical Operators • Boolean logical operators in Java are used to perform logical operations on boolean values. • These operators return a boolean result based on the logic of the expressions. • The Boolean logical operators in java are: • The logical Boolean operators, &, |, and ^, operate on boolean values in the same way that they operate on the bits of an integer. • The logical ! operator inverts the Boolean state: !true == false and !false == true. • The following table shows the effect of each logical operation: Short-Circuit Logical Operators • Java provides two interesting Boolean operators: && and || • These are secondary versions of the Boolean AND and OR operators, and are known as short-circuit logical operators. • These operators are called short-circuit operators because they evaluate the second operand only if it is necessary to determine the result of the expression. • This can make expressions more efficient by avoiding unnecessary evaluations. Logical AND (&&) • The logical AND operator (&&) evaluates the second operand only if the first operand is true. If the first operand is false, the entire expression is false and the second operand is not evaluated. Logical OR (||) • The logical OR operator (||) evaluates the second operand only if the first operand is false. If the first operand is true, the entire expression is true, and the second operand is not evaluated. The Assignment Operator • The assignment operator in Java is used to assign a value to a variable. • The assignment operator is the single equal sign, =. • It has this general form: var = expression; • Here, the type of var must be compatible with the type of expression. • The assignment operator allows you to create a chain of assignments. • For example, consider this fragment: int x, y, z; • x = y = z = 100; // set x, y, and z to 100 The ? Operator • Java includes a special ternary (three-way) operator that can replace certain types of if-then-else statements. • This operator is the ? • The ? has this general form: expression1 ? expression2 : expression3 • Here, expression1 can be any expression that evaluates to a boolean value. • If expression1 is true, then expression2 is evaluated; otherwise, expression3 is evaluated. • The result of the ? operation is that of the expression evaluated. • Both expression2 and expression3 are required to return the same type, which can’t be void. • For example: ratio = denom == 0 ? 0 : num / denom; • If denom equals zero, then the expression between the question mark and the colon is evaluated and used as the value of the entire ? expression. • If denom does not equal zero, then the expression after the colon is evaluated and used for the value of the entire ? expression. • The result produced by the ? operator is then assigned to ratio. The Bitwise Operators • Java defines several bitwise operators that can be applied to the integer types, long, int, short, char, and byte. • These operators act upon the individual bits of their operands. • They are summarized in the following table: The Bitwise Logical Operators • The bitwise logical operators are &, |, ^, and ~. • The bitwise operators are applied to each individual bit within each operand. • The following table shows the outcome of each operation.
The Left Shift
• The left shift operator, <<, shifts all of the bits in a value to the left a specified number of times. • It has this general form: value << num • Here, num specifies the number of positions to left-shift the value in value The Right Shift • The right shift operator, >>, shifts all of the bits in a value to the right a specified number of times. Its general form is shown here: value >> num Unsigned right shift operator (>>>) • The unsigned right shift operator (>>>) shifts a bit pattern to the right. • This operator fills the leftmost bits with zeros, regardless of the sign of the original value. • This is different from the signed right shift operator (>>) which fills the leftmost bits with the sign bit (0 for positive numbers and 1 for negative numbers), thereby preserving the sign of the original value. Bitwise Operator Compound Assignments • Bitwise operators can be combined with assignment operators to create compound assignment operators. • These operators perform a bitwise operation on the variable and assign the result back to the variable in a single step. • Here's a list of bitwise operator compound assignments : • Bitwise AND Assignment (&=) • Bitwise OR Assignment (|=) • Bitwise XOR Assignment (^=) • Left Shift Assignment (<<=) • Right Shift Assignment (>>=) • Unsigned Right Shift Assignment(>>>=) operator precedence • Operator precedence determines the order in which operators ar evaluated in expressions. • Operators with higher precedence are evaluated before those with lower precedence. • When operators have the same precedence, their associativity determines the order of evaluation. • Here's a summary of operator precedence and associativity in Java, from highest to lowest precedence: Using Parentheses • Parentheses raise the precedence of the operations that are inside them. • This is often necessary to obtain the result you desire. • For example, consider the following expression: a >> b + 3 • This expression first adds 3 to b and then shifts a right by that result. • That is, this expression can be rewritten using redundant parentheses like this: a >> (b + 3) • If you want to first shift a right by b positions and then add 3 to that result, you will need to parenthesize the expression like this: (a >> b) + 3 • In addition to altering the normal precedence of an operator, parentheses can sometimes be used to help clarify the meaning of an expression. Control Statements • Programming language uses control statements to cause the flow of execution to advance and branch based on changes to the state of a program. • Java’s program control statements can be put into the following categories: selection, iteration, and jump. • Selection statements allow your program to choose different paths of execution based upon the outcome of an expression or the state of a variable. • Iteration statements enable program execution to repeat one or more statements (that is, iteration statements form loops). • Jump statements allow your program to execute in a nonlinear fashion. Java’s Selection Statements
• Java supports two selection statements: if and switch.
• These statements allow you to control the flow of your program’s execution based upon conditions known only during run time. if • The if statement is Java’s conditional branch statement. • It can be used to route program execution through two different paths. • Here is the general form of the if statement: if (condition) statement1; else statement2; • Here, each statement may be a single statement or a compound statement enclosed in curly braces (that is, a block). • The condition is any expression that returns a boolean value. • The else clause is optional. • The if works like this: If the condition is true, then statement1 is executed. • Otherwise, statement2 (if it exists) is executed. • In no case will both statements be executed. Nested ifs • A nested if is an if statement that is the target of another if or else. • Nested ifs are very common in programming. • When you nest ifs, the main thing to remember is that an else statement always refers to the nearest if statement that is within the same block as the else and that is not already associated with an else. The if-else-if Ladder • A common programming construct that is based upon a sequence of nested ifs is the if-else-if ladder. It looks like this: if(condition) statement; else if(condition) statement; else if(condition) statement; ... else statement; • The if statements are executed from the top down. As soon as one of the conditions controlling the if is true, the statement associated with that if is executed, and the rest of the ladder is bypassed. • If none of the conditions is true, then the final else statement will be executed. • The final else acts as a default condition; that is, if all other conditional tests fail, then the last else statement is performed. • If there is no final else and all other conditions are false, then no action will take place. switch • The switch statement is Java’s multiway branch statement. • It provides an easy way to dispatch execution to different parts of your code based on the value of an expression. • It provides a better alternative than a large series of if-else-if statements. • Here is the general form of a switch statement: switch (expression) { case value1: // statement sequence break; case value2: // statement sequence break; ... case valueN: // statement sequence break; default: // default statement sequence } • The expression must be of type byte, short, int, or char; • each of the values specified in the case statements must be of a type compatible with the expression. • Each case value must be a unique literal (that is, it must be a constant, not a variable). • Duplicate case values are not allowed. • The switch statement works like this: • The value of the expression is compared with each of the literal values in the case statements. • If a match is found, the code sequence following that case statement is executed. • If none of the constants matches the value of the expression, then the default statement is executed. • However, the default statement is optional. • If no case matches and no default is present, then no further action is taken. • The break statement is used inside the switch to terminate a statement sequence. • When a break statement is encountered, execution branches to the first line of code that follows the • entire switch statement. • This has the effect of “jumping out” of the switch. Nested switch Statements • You can use a switch as part of the statement sequence of an outer switch. • This is called a nested switch. Since a switch statement defines its own block, no conflicts arise between the case constants in the inner switch and those in the outer switch. Iteration Statements • Java’s iteration statements are for, while, and do-while. • These statements create what we commonly call loops. • A loop repeatedly executes the same set of instructions until a termination condition is met. while • The while loop is Java’s most fundamental loop statement. • It repeats a statement or block while its controlling expression is true. • Here is its general form: while(condition) { // body of loop } • The condition can be any Boolean expression. • The body of the loop will be executed as long as the conditional expression is true. • When condition becomes false, control passes to the next line of code immediately following the loop. • The curly braces are unnecessary if only a single statement is being repeated. do-while • If the conditional expression controlling a while loop is initially false, then the body of the loop will not be executed at all. • The do-while loop always executes its body at least once, because its conditional expression is at the bottom of the loop. • Its general form is do { // body of loop } while (condition); • Each iteration of the do-while loop first executes the body of the loop and then evaluates the conditional expression. • If this expression is true, the loop will repeat. • Otherwise, the loop terminates. • condition must be a Boolean expression. For • There are two forms of the for loop. • The first is the traditional form and the second is the new “for-each” form. • The general form of the traditional for statement: for(initialization; condition; iteration) { // body } • If only one statement is being repeated, there is no need for the curly braces. • The for loop operates as follows. • When the loop first starts, the initialization portion of the loop is executed. • This is an expression that sets the value of the loop control variable, which acts as a counter that controls the loop. • The initialization expression is only executed once. • Next, condition is evaluated. This must be a Boolean expression. • It usually tests the loop control variable against a target value. • If this expression is true, then the body of the loop is executed. If it is false, the loop terminates. • Next, the iteration portion of the loop is executed. This is usually an expression that increments or decrements the loop control variable. • The loop then iterates, first evaluating the conditional expression, then executing the body of the loop, and then executing the iteration expression with each pass. • This process repeats until the controlling expression is false. The For-Each Version of the for Loop • The for-each loop, introduced in Java 5, is a simpler and more readable way to iterate over arrays or collections. • A foreach style loop is designed to cycle through a collection of objects, such as an array, in strictly • sequential fashion, from start to finish • It eliminates the need for an explicit counter and simplifies the code, making it more concise and less prone to errors. • The syntax of the for-each loop is: for (Type item : collection) { // statement-block } • Here, type specifies the type and item specifies the name of an iteration variable that will receive the elements from a collection, one at a time, from beginning to end. • The collection being cycled through is specified by collection. • With each iteration of the loop, the next element in the collection is retrieved and stored in item. • The loop repeats until all elements in the collection have been obtained. • Because the iteration variable receives values from the collection, type must be the same as (or compatible with) the elements stored in the collection. • Thus, when iterating over arrays, type must be compatible with the base type of the array. Local Variable Type Inference in a for Loop • Local variable type inference, introduced in Java 10, allows the use of the var keyword to declare local variables without explicitly specifying their type. • This feature can also be used in the context of a for loop, including both traditional for loops and for-each loops. • This can make your code more concise and readable. Using var in a Traditional for loop • In a traditional loop, you can use var to infer the type of the loop variable: public class VarInForLoop { public static void main(String[] args) { for (var i = 0; i < 10; i++) { System.out.println(i); } } } • In this example: var=0 declares and initializes the loop variable i as int • The type of i is inferred from the initializer. Using var in a For-Each Loop In a for-each loop, you can use var to infer the type of the loop variable based on the type of the elements in the array or collection: import java.util.List; public class VarInForEachLoop { public static void main(String[] args) { List<String> fruits = List.of("Apple", "Banana", "Cherry");
for (var fruit : fruits) {
System.out.println(fruit); } } } In this example: var fruit is used to declare the loop variable. The type of fruit is inferred to be String based on the type of elements in the fruits list. Nested Loops • Like all other programming languages, Java allows loops to be nested. • That is, one loop may be inside another. • For example, here is a program that nests for loops: // Loops may be nested. class Nested { public static void main(String args[]) { int i, j; for(i=0; i<10; i++) { for(j=i; j<10; j++) System.out.print("."); System.out.println(); } } } Jump Statements • Java supports three jump statements: break, continue, and return. • These statements transfer control to another part of your program. Using break • In Java, the break statement has three uses. • First, it terminates a statement sequence in a switch statement. • Second, it can be used to exit a loop. • Third, it can be used as a “civilized” form of goto. Using break to Exit a Loop • By using break, you can force immediate termination of a loop, bypassing the conditional expression and any remaining code in the body of the loop. • When a break statement is encountered inside a loop, the loop is terminated and program control resumes at the next statement following the loop. • For example: for(int i=0; i<100; i++) { if(i == 10) break; // terminate loop if i is 10 System.out.println("i: " + i); } System.out.println("Loop complete."); } Using break as a Form of Goto • In addition to its uses with the switch statement and loops, the break statement can also be employed by itself to provide a “civilized” form of the goto statement. • Java does not have a goto statement because it provides a way to branch in an arbitrary and unstructured manner. • This usually makes goto-ridden code hard to understand and hard to maintain. • It also prohibits certain compiler optimizations. • Java defines an expanded form of the break statement. • By using this form of break, you can break out of one or more blocks of code. • These blocks need not be part of a loop or a switch. They can be any block. • break gives you the benefits of a goto without its problems. • The general form of the labeled break statement is shown here: break label; • Most often, label is the name of a label that identifies a block of code. • This can be a stand-alone block of code but it can also be a block that is the target of another statement. • When this form of break executes, control is transferred out of the named block. Using continue • Continue statement is used inside loops to skip the current iteration and proceed to the next iteration. • This statement can be particularly useful when you want to skip certain values or conditions within a loop without exiting the loop entirely. • In while and do-while loops, a continue statement causes control to be transferred directly to the conditional expression that controls the loop. • In a for loop, control goes first to the iteration portion of the for statement and then to the conditional expression. • For all three loops, any intermediate code is bypassed. Using continue with Labels • In Java, you can also use the continue statement with labels to specify which loop to continue. This can be useful when you have nested loops and want to control the flow more precisely. return • The return statement is used to explicitly return from a method. • That is, it causes program control to transfer back to the caller of the method. • At any time in a method the return statement can be used to cause execution to branch back to the caller of the method. • Thus, the return statement immediately terminates the method in which it is executed. Using return in Methods 1. Void Methods In methods that do not return a value (i.e., methods with a void return type), the return statement is used to exit the method prematurely. 2. Methods with Return Values For methods that return a value, the return statement is used to provide that value to the caller. The type of the return value must match the method's declared return type.