Home Blog Page 96

Strings in Java – String Class, Immutable Nature, StringBuilder and StringBuffer

0
java spring boot course
java spring boot course

Table of Contents

  1. Introduction to Strings in Java
  2. The String Class
  3. String Declaration and Initialization
  4. String Immutability
  5. Common String Methods
  6. String Comparison
  7. String Concatenation and Performance
  8. StringBuilder vs StringBuffer
  9. Real-world Use Cases
  10. Summary and What’s Next

1. Introduction to Strings in Java

In Java, strings are objects that represent sequences of characters. The String class in Java is widely used for text manipulation, storing user input, file data, and more. String handling is a fundamental part of programming, and Java provides a rich set of tools to work with them effectively.

Unlike primitive types, strings in Java are objects and are part of the java.lang package, which is automatically imported.


2. The String Class

The String class in Java is final, meaning it cannot be inherited. It represents immutable character sequences, and once a String object is created, its value cannot be changed.

Internally, Java strings are backed by a character array and stored in a special area called the string constant pool, which helps in memory optimization.


3. String Declaration and Initialization

Using string literals

String name = "John";

When using string literals, Java first checks if the string already exists in the constant pool. If it does, it reuses the reference.

Using new keyword

String name = new String("John");

This creates a new object in the heap, even if the same string exists in the pool.


4. String Immutability

Java strings are immutable, meaning once created, their values cannot be modified.

Example:

String str = "Hello";
str.concat(" World");
System.out.println(str); // Outputs: Hello

Although concat is called, the original string remains unchanged. This behavior improves security and caching but can lead to performance overhead in certain scenarios.

Immutability is one reason strings are safe to use in multithreaded environments without synchronization.


5. Common String Methods

Java provides numerous methods in the String class for various operations:

  • length(): Returns the number of characters
  • charAt(int index): Returns the character at a specified index
  • substring(int beginIndex, int endIndex): Extracts a portion of the string
  • toLowerCase(), toUpperCase(): Changes case
  • trim(): Removes leading and trailing whitespaces
  • equals(), equalsIgnoreCase(): Compares two strings
  • indexOf(), lastIndexOf(): Searches for characters or substrings
  • replace(): Replaces characters or substrings

Example:

String str = "  Java Programming  ";
System.out.println(str.trim().toUpperCase()); // Output: JAVA PROGRAMMING

6. String Comparison

Using ==

Compares reference, not actual content.

String a = "Java";
String b = "Java";
System.out.println(a == b); // true, same reference from pool

String c = new String("Java");
System.out.println(a == c); // false, different objects

Using equals()

Compares content.

System.out.println(a.equals(c)); // true

Using compareTo()

Lexicographically compares two strings.

System.out.println("apple".compareTo("banana")); // Negative value

7. String Concatenation and Performance

Strings can be concatenated using + or concat().

String result = "Hello " + "World";

However, since strings are immutable, repeated concatenation creates multiple intermediate objects, which can degrade performance in large loops.

Inefficient example:

String result = "";
for (int i = 0; i < 1000; i++) {
result += i;
}

Each + creates a new string, leading to O(n^2) complexity.


8. StringBuilder vs StringBuffer

To avoid inefficiencies of immutable strings in repetitive operations, Java provides:

StringBuilder

  • Mutable, not thread-safe
  • Better for single-threaded scenarios
StringBuilder sb = new StringBuilder("Hello");
sb.append(" World");
System.out.println(sb.toString()); // Output: Hello World

StringBuffer

  • Mutable, thread-safe (synchronized)
  • Better for multithreaded environments
StringBuffer sbf = new StringBuffer("Java");
sbf.append(" Rocks");
System.out.println(sbf); // Output: Java Rocks
FeatureStringStringBuilderStringBuffer
MutabilityImmutableMutableMutable
Thread-safeYesNoYes
PerformanceSlow for loopsFastSlower than SB

9. Real-world Use Cases

Parsing user input

Scanner sc = new Scanner(System.in);
String input = sc.nextLine().trim();
if (input.equalsIgnoreCase("yes")) {
System.out.println("Confirmed");
}

Constructing a URL

StringBuilder url = new StringBuilder("https://example.com/");
url.append("user/").append("123");
System.out.println(url.toString());

Logging

Strings are often used to log system output or build dynamic messages.

String msg = String.format("User %s has logged in at %s", username, loginTime);

10. Summary and What’s Next

In this module, we covered:

  • How strings work in Java and their immutable nature
  • How to declare, initialize, and manipulate strings
  • Efficient string handling using StringBuilder and StringBuffer
  • Key methods for comparing, transforming, and parsing strings
  • Use cases and performance considerations

Mastering strings is vital because they appear in nearly every real-world Java application, whether you’re handling input, processing text, or working with APIs.

Arrays in Java – Single & Multi-dimensional Arrays, Array Operations

0
java spring boot course
java spring boot course

Table of Contents

  1. What Are Arrays?
  2. Advantages of Using Arrays
  3. Declaring and Initializing Arrays
  4. Accessing and Modifying Elements
  5. Iterating Through Arrays
  6. Multi-dimensional Arrays
  7. Common Array Operations
  8. Arrays vs ArrayList
  9. Real-world Examples
  10. Summary and What’s Next

1. What Are Arrays?

In Java, an array is a data structure that allows you to store multiple values of the same data type in a single variable. Arrays are fixed in size and indexed, meaning that each element can be accessed using its position (or index), starting from 0.

Arrays are one of the most basic and essential constructs in programming, used in countless applications from mathematical operations to organizing large datasets.


2. Advantages of Using Arrays

  • Efficiency: Arrays allow you to group related data together, making storage and manipulation more efficient.
  • Indexed Access: You can directly access any element in constant time using its index.
  • Ease of Iteration: Arrays can easily be looped through, especially with constructs like the enhanced for-loop.
  • Memory Management: Java arrays are stored in contiguous memory locations, improving data locality and access speed.

3. Declaring and Initializing Arrays

Declaration

int[] numbers;
String[] names;

Initialization with size

int[] numbers = new int[5];  // Array of 5 integers

Initialization with values

int[] numbers = {10, 20, 30, 40, 50};

Assigning elements manually

numbers[0] = 10;
numbers[1] = 20;

Arrays in Java are objects, so when declared, memory is allocated on the heap.


4. Accessing and Modifying Elements

Each element in an array is accessed using its index:

System.out.println(numbers[2]); // prints 30
numbers[2] = 35; // modifies the third element

If you try to access an index outside the array bounds, Java throws an ArrayIndexOutOfBoundsException.


5. Iterating Through Arrays

Using a traditional for loop:

for (int i = 0; i < numbers.length; i++) {
System.out.println(numbers[i]);
}

Using an enhanced for-each loop:

for (int number : numbers) {
System.out.println(number);
}

The enhanced loop is simpler but doesn’t give access to indices. Use it when you just need values.


6. Multi-dimensional Arrays

Java also supports arrays of arrays, often used for matrices and tables.

Declaration and Initialization

int[][] matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};

Accessing Elements

System.out.println(matrix[1][2]); // prints 6

Iterating

for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
System.out.print(matrix[i][j] + " ");
}
System.out.println();
}

Multi-dimensional arrays are arrays of arrays in Java, not flat 2D structures like in some other languages.


7. Common Array Operations

Finding Maximum or Minimum

int max = numbers[0];
for (int i = 1; i < numbers.length; i++) {
if (numbers[i] > max) {
max = numbers[i];
}
}

Reversing an Array

for (int i = 0; i < numbers.length / 2; i++) {
int temp = numbers[i];
numbers[i] = numbers[numbers.length - 1 - i];
numbers[numbers.length - 1 - i] = temp;
}

Copying Arrays

int[] copy = Arrays.copyOf(numbers, numbers.length);

Java provides utility classes like Arrays to assist with common array operations like sorting, searching, and copying.


8. Arrays vs ArrayList

FeatureArrayArrayList
SizeFixedDynamic
Type SafetyPrimitive & ObjectsObjects only
PerformanceSlightly fasterMore flexible
MethodsNo built-inRich API

When working with dynamic or frequently resized collections, consider using ArrayList from the java.util package instead of arrays.


9. Real-world Examples

Example 1: Storing student scores

int[] scores = new int[5];
Scanner sc = new Scanner(System.in);
for (int i = 0; i < scores.length; i++) {
System.out.print("Enter score " + (i + 1) + ": ");
scores[i] = sc.nextInt();
}

Example 2: Basic Matrix Multiplication (2×2)

int[][] A = {{1, 2}, {3, 4}};
int[][] B = {{5, 6}, {7, 8}};
int[][] C = new int[2][2];

for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
for (int k = 0; k < 2; k++) {
C[i][j] += A[i][k] * B[k][j];
}
}
}

This example demonstrates the power of multi-dimensional arrays in mathematical computation.


10. Summary and What’s Next

In this module, we covered:

  • The basics of arrays in Java, including declaration, initialization, and iteration
  • Working with both single and multi-dimensional arrays
  • Performing key operations like searching, reversing, and copying
  • Understanding differences between arrays and ArrayList

Arrays form the foundation of many data structures and are critical to efficient memory and data management in Java.

Loops in Java – for, while, do-while, break and continue

0
java spring boot course
java spring boot course

Table of Contents

  1. Introduction to Loops
  2. The for Loop
  3. The while Loop
  4. The do-while Loop
  5. Loop Control Statements: break and continue
  6. Infinite Loops
  7. Nested Loops
  8. Real-World Examples
  9. Summary and What’s Next

1. Introduction to Loops

Loops are used in programming to execute a block of code repeatedly until a certain condition is met. Java supports three main types of loops:

  • for loop
  • while loop
  • do-while loop

Each loop type has its specific use case, but all can be used to achieve similar outcomes. Loops help reduce redundancy, automate repetitive tasks, and improve code readability.


2. The for Loop

The for loop is best when you know in advance how many times you want to iterate.

Syntax:

for (initialization; condition; update) {
// code block to be executed
}

Example:

for (int i = 1; i <= 5; i++) {
System.out.println("Iteration: " + i);
}

Explanation:

  • Initialization: Runs once at the beginning, e.g., int i = 1.
  • Condition: Checked before each iteration; loop runs if it’s true.
  • Update: Executed after each iteration, e.g., i++.

3. The while Loop

The while loop is used when the number of iterations is not known in advance. It checks the condition before the loop body.

Syntax:

while (condition) {
// code block to be executed
}

Example:

int i = 1;
while (i <= 5) {
System.out.println("Count: " + i);
i++;
}

The loop continues as long as i <= 5 is true.


4. The do-while Loop

The do-while loop is similar to the while loop, but it guarantees at least one execution of the loop body, since the condition is evaluated after the loop body.

Syntax:

do {
// code block to be executed
} while (condition);

Example:

int i = 1;
do {
System.out.println("Running: " + i);
i++;
} while (i <= 5);

This loop runs at least once, even if the condition is initially false.


5. Loop Control Statements: break and continue

The break Statement

Used to exit the loop prematurely when a certain condition is met.

for (int i = 1; i <= 10; i++) {
if (i == 5) {
break;
}
System.out.println(i);
}

This loop prints numbers 1 to 4 and then exits when i becomes 5.

The continue Statement

Skips the current iteration and jumps to the next one.

for (int i = 1; i <= 5; i++) {
if (i == 3) {
continue;
}
System.out.println(i);
}

This loop prints 1, 2, 4, 5 (skips 3).


6. Infinite Loops

An infinite loop keeps running forever unless forcibly terminated. Can be useful in event-driven or server applications.

Example:

while (true) {
// keep listening for connections
}

Use infinite loops with care, ensuring there’s a break condition or manual stop mechanism.


7. Nested Loops

You can place a loop inside another loop to perform complex iterations like matrix processing or pattern printing.

Example:

for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 2; j++) {
System.out.println("i = " + i + ", j = " + j);
}
}

8. Real-World Examples

Printing a Table of a Number

int number = 7;
for (int i = 1; i <= 10; i++) {
System.out.println(number + " * " + i + " = " + (number * i));
}

Counting User Inputs Until a Sentinel Value

Scanner scanner = new Scanner(System.in);
int input;
do {
System.out.print("Enter number (0 to quit): ");
input = scanner.nextInt();
} while (input != 0);

Searching for an Element

int[] arr = {3, 5, 7, 9};
int target = 7;
boolean found = false;

for (int i = 0; i < arr.length; i++) {
if (arr[i] == target) {
found = true;
break;
}
}
System.out.println("Element found: " + found);

9. Summary and What’s Next

In this module, we learned:

  • The structure and use cases of for, while, and do-while loops
  • How to control loop flow using break and continue
  • Common looping patterns including nested loops and infinite loops

Understanding loops is essential to solving repetitive tasks and optimizing code efficiency.

Control Flow in Java – if, else, switch, and Ternary Operator

0
java spring boot course
java spring boot course

Table of Contents

  1. Introduction to Control Flow
  2. The if Statement
  3. The else and else if Statements
  4. The switch Statement
  5. The Ternary (Conditional) Operator
  6. Nested if Statements
  7. Common Mistakes and Pitfalls
  8. Real-World Use Cases
  9. Summary and What’s Next

1. Introduction to Control Flow

Control flow statements in Java allow you to control the execution flow of your program based on certain conditions. These conditions help the program make decisions, repeat actions, or perform alternate actions.

There are several control flow structures in Java:

  • Conditional statements (if, else if, else, switch)
  • Looping statements (for, while, do-while)
  • Jump statements (break, continue, return)

In this module, we will explore the if, else, switch, and the ternary operator, which are used for making decisions in the program.


2. The if Statement

The if statement is the most basic form of decision-making in Java. It allows you to execute a block of code only if a particular condition is true.

Syntax:

if (condition) {
// code to execute if condition is true
}

Example:

int number = 10;
if (number > 5) {
System.out.println("Number is greater than 5.");
}

In the above example, the condition number > 5 is true, so the message is printed.

Notes:

  • The condition inside the if statement must be a boolean expression.
  • If the condition is false, the code inside the block is skipped.

3. The else and else if Statements

The else statement can be used to specify a block of code that will execute if the if condition evaluates to false.

Syntax:

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

Example:

int number = 3;
if (number > 5) {
System.out.println("Number is greater than 5.");
} else {
System.out.println("Number is less than or equal to 5.");
}

The else if statement is used when you want to check multiple conditions. It allows you to specify several alternative conditions.

Syntax:

if (condition1) {
// code to execute if condition1 is true
} else if (condition2) {
// code to execute if condition2 is true
} else {
// code to execute if all conditions are false
}

Example:

int number = 7;
if (number > 10) {
System.out.println("Number is greater than 10.");
} else if (number > 5) {
System.out.println("Number is greater than 5 but less than or equal to 10.");
} else {
System.out.println("Number is 5 or less.");
}

4. The switch Statement

The switch statement is another form of decision-making. It is often used when you need to test one variable against multiple potential values.

Syntax:

switch (variable) {
case value1:
// code to execute if variable == value1
break;
case value2:
// code to execute if variable == value2
break;
default:
// code to execute if variable does not match any of the above values
}

Example:

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:
System.out.println("Saturday");
break;
case 7:
System.out.println("Sunday");
break;
default:
System.out.println("Invalid day");
}

Notes:

  • The break statement is used to terminate the switch statement and exit the block.
  • If the break statement is omitted, the program will “fall through” to the next case statement until a break is encountered.
  • The default case is optional and runs if none of the case conditions match.

5. The Ternary (Conditional) Operator

The ternary operator provides a compact way to perform a simple if-else decision in a single line.

Syntax:

condition ? expression1 : expression2;

If the condition is true, expression1 is executed; if the condition is false, expression2 is executed.

Example:

int number = 8;
String result = (number > 5) ? "Greater than 5" : "Less than or equal to 5";
System.out.println(result);

In the above example, the condition (number > 5) evaluates to true, so the output will be “Greater than 5.”


6. Nested if Statements

You can nest if statements inside each other to perform more complex decision-making. This is useful when you need to evaluate multiple conditions in a hierarchical manner.

Example:

int number = 12;
if (number > 10) {
if (number % 2 == 0) {
System.out.println("Number is greater than 10 and even.");
} else {
System.out.println("Number is greater than 10 but odd.");
}
} else {
System.out.println("Number is less than or equal to 10.");
}

7. Common Mistakes and Pitfalls

  • Missing break statement in switch: If you forget the break statement, the program will continue to execute all the following cases until a break is encountered, potentially leading to unintended results.
  • Misplaced parentheses: Incorrect placement of parentheses can lead to logical errors, especially when dealing with multiple conditions. Always ensure that conditions are correctly grouped.

8. Real-World Use Cases

  • Login Validation: Using if statements to validate user input in a login form. String username = "admin"; String password = "password123"; if (username.equals("admin") && password.equals("password123")) { System.out.println("Login successful."); } else { System.out.println("Invalid credentials."); }
  • Menu Selection: Using switch statements to implement menu options. int option = 2; switch (option) { case 1: System.out.println("Start game"); break; case 2: System.out.println("Load game"); break; default: System.out.println("Invalid option"); }

9. Summary and What’s Next

In this module, we covered:

  • The if, else, and else if statements for conditional logic
  • The switch statement for handling multiple conditions
  • The ternary operator for concise conditional expressions
  • Nested if statements for more complex conditions

Operators in Java (Arithmetic, Relational, Logical)

0
java spring boot course
java spring boot course

Table of Contents

  1. Introduction to Operators in Java
  2. Arithmetic Operators
  3. Relational (Comparison) Operators
  4. Logical Operators
  5. Assignment Operators
  6. Unary Operators
  7. Bitwise Operators (Bonus Section)
  8. Operator Precedence and Associativity
  9. Common Mistakes to Avoid
  10. Real-World Use Cases and Examples
  11. Summary and What’s Next

1. Introduction to Operators in Java

In Java, operators are special symbols or keywords used to perform operations on variables and values. They are the backbone of any expression and play a critical role in controlling program logic and data manipulation. Java includes a wide range of operators to support arithmetic calculations, logical decision-making, and even low-level bit manipulation.

Operators work with operands. For example, in the expression a + b, the + operator works on operands a and b.

Operators can be categorized based on their functionality and the number of operands they work with:

  • Unary Operators (one operand)
  • Binary Operators (two operands)
  • Ternary Operator (three operands, covered in the next module)

2. Arithmetic Operators

Arithmetic operators are used to perform basic mathematical operations. They always return numeric results and can be used with all numeric primitive types (int, float, double, etc.).

OperatorDescriptionExampleResult
+Addition10 + 515
-Subtraction10 - 55
*Multiplication10 * 550
/Division10 / 52
%Modulus (remainder)10 % 31

Integer Division vs Floating-point Division

When you divide two integers in Java, the result is also an integer (the decimal part is truncated):

int result = 7 / 2; // result = 3

To get an accurate floating-point result, cast one operand to a float or double:

double result = 7 / 2.0; // result = 3.5

3. Relational (Comparison) Operators

Relational operators compare two values and return a boolean result. These are essential in control flow and decision-making.

OperatorDescriptionExampleResult
==Equal to5 == 5true
!=Not equal to5 != 4true
>Greater than5 > 3true
<Less than5 < 3false
>=Greater than or equal to5 >= 5true
<=Less than or equal to4 <= 5true

These are primarily used in if, while, for, and switch statements.


4. Logical Operators

Logical operators allow combining multiple conditions. They work with boolean values only.

OperatorDescriptionSyntaxExample
&&Logical ANDcondition1 && condition2true && false → false
``Logical OR
!Logical NOT!condition!true → false

Short-circuiting Behavior

Java uses short-circuit evaluation:

  • &&: If the first operand is false, the second operand is not evaluated.
  • ||: If the first operand is true, the second operand is not evaluated.

This behavior improves performance and avoids potential exceptions, such as NullPointerException.


5. Assignment Operators

Assignment operators are used to assign values to variables. Java supports shorthand operators for updating values.

OperatorDescriptionExampleEquivalent
=Assigna = 10
+=Add and assigna += 5a = a + 5
-=Subtract and assigna -= 3a = a - 3
*=Multiply and assigna *= 2a = a * 2
/=Divide and assigna /= 4a = a / 4
%=Modulus and assigna %= 3a = a % 3

These are helpful in loops and arithmetic-heavy programs.


6. Unary Operators

Unary operators work with a single operand.

OperatorDescriptionExampleResult
+Unary plus (no effect)+aa
-Unary minus-aNegates a
++Increment (prefix/postfix)++a, a++Increments a
--Decrement (prefix/postfix)--a, a--Decrements a
!Logical complement!truefalse

Prefix vs Postfix

int a = 5;
int b = ++a; // b = 6, a = 6 (prefix)
int c = a++; // c = 6, a = 7 (postfix)

7. Bitwise Operators (Bonus Section)

Bitwise operators are used for performing operations at the bit level, primarily useful in low-level programming and optimization.

OperatorDescriptionExample
&Bitwise ANDa & b
``Bitwise OR
^Bitwise XORa ^ b
~Bitwise NOT~a
<<Left shifta << 2
>>Right shifta >> 2

Example:

int x = 5;        // 0101 in binary
int y = 3; // 0011 in binary
System.out.println(x & y); // Output: 1 (0001)

8. Operator Precedence and Associativity

When multiple operators are used in an expression, Java evaluates them based on precedence and associativity.

Precedence (High to Low)

  1. Postfix: expr++, expr--
  2. Unary: ++expr, --expr, +, -, !
  3. Multiplicative: *, /, %
  4. Additive: +, -
  5. Relational: <, <=, >, >=
  6. Equality: ==, !=
  7. Logical AND: &&
  8. Logical OR: ||
  9. Assignment: =, +=, -=, etc.

Associativity

  • Most binary operators are left-to-right associative.
  • Assignment operators are right-to-left associative.

Use parentheses to make expressions clear and override default precedence.


9. Common Mistakes to Avoid

  • Using = instead of == in conditions (if (a = b) instead of if (a == b))
  • Forgetting short-circuit behavior in && and ||
  • Integer division errors due to type mismatch
  • Using post-increment when pre-increment is needed (or vice versa)
  • Applying logical operators to non-boolean operands

10. Real-World Use Cases and Examples

  • Use relational and logical operators for input validation: if (age >= 18 && citizenship.equals("Indian")) { System.out.println("Eligible to vote."); }
  • Arithmetic operators in billing applications: double total = quantity * pricePerUnit + tax;
  • Bitwise operations in graphics and cryptography
  • Assignment operators in loops to update counters

11. Summary and What’s Next

In this module, you have covered:

  • Different categories of Java operators
  • Syntax and examples for arithmetic, relational, logical, and assignment operators
  • Operator precedence and associativity
  • Common mistakes and real-world use cases

Understanding how and when to use each type of operator helps you write cleaner and more efficient code.