01. π Java Fundamentals
Java is a high-level, class-based, object-oriented programming language designed to have as few implementation dependencies as possible. It was created by James Gosling at Sun Microsystems (now owned by Oracle) in 1995.
Why Learn Java?
Java remains one of the most popular programming languages because:
1. Platform Independence: Write Once, Run Anywhere (WORA)
2. Object-Oriented: Pure OOP language
3. Robust & Secure: Memory management, exception handling
4. Multithreading: Built-in support for concurrent programming
5. Vast Ecosystem: Android apps, web apps, enterprise systems
Java Architecture
- Java Source Code: .java files
- Java Compiler (javac): Compiles to bytecode
- Bytecode: .class files (platform-independent)
- JVM (Java Virtual Machine): Executes bytecode
- JRE (Java Runtime Environment): JVM + libraries
- JDK (Java Development Kit): JRE + development tools
Example: Your First Java Program
// Simple Java program to demonstrate basic structure
public class HelloWorld {
// Main method - entry point of Java program
public static void main(String[] args) {
// Print "Hello, World!" to console
System.out.println("Hello, World!");
// Basic variables
int number = 42;
String message = "Learning Java";
// Using variables
System.out.println(message);
System.out.println("The answer is: " + number);
// Simple calculation
int sum = 5 + 3;
System.out.println("5 + 3 = " + sum);
// Conditional statement
if (number > 10) {
System.out.println("Number is greater than 10");
} else {
System.out.println("Number is 10 or less");
}
// Loop example
System.out.println("Counting from 1 to 3:");
for (int i = 1; i <= 3; i++) {
System.out.println("Count: " + i);
}
}
}
Note: Java is case-sensitive. Every Java program must have a class with a main method. The class name should match the filename (HelloWorld.java). Use proper indentation for readability.
02. π Java Syntax Basics
Java syntax is similar to C and C++, but with stricter rules and fewer low-level features. Understanding Java syntax is crucial for writing correct and efficient code.
Basic Syntax Rules
- Case Sensitivity: Java is case-sensitive
- Class Names: Should start with uppercase letter (PascalCase)
- Method Names: Should start with lowercase letter (camelCase)
- Program File Name: Must match class name exactly
- Main Method: Required for program execution
- Statements: Must end with semicolon (;)
- Blocks: Enclosed in curly braces {}
Java Comments
Comments are essential for documentation and code readability:
1. Single-line: // This is a comment
2. Multi-line: /* This is a multi-line comment */
3. Documentation: /** This is a Javadoc comment */
Example: Java Syntax in Action
// File: SyntaxDemo.java
// This class demonstrates Java syntax rules
// Class declaration (PascalCase)
public class SyntaxDemo {
// Constant (UPPER_SNAKE_CASE)
public static final double PI = 3.14159;
// Instance variable (camelCase)
private int instanceCount;
// Constructor (same name as class)
public SyntaxDemo() {
this.instanceCount = 0;
}
// Method declaration (camelCase)
public void demonstrateSyntax() {
// Local variable (camelCase)
int localVariable = 10;
// If statement
if (localVariable > 5) {
System.out.println("Variable is greater than 5");
}
// For loop
for (int i = 0; i < 3; i++) {
System.out.println("Loop iteration: " + i);
}
// While loop
int counter = 0;
while (counter < 2) {
System.out.println("While loop count: " + counter);
counter++;
}
// Do-while loop
int number = 5;
do {
System.out.println("Do-while executes at least once");
number--;
} while (number > 0);
// Switch statement
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;
default:
System.out.println("Other day");
}
}
// Main method - program entry point
public static void main(String[] args) {
// Creating object
SyntaxDemo demo = new SyntaxDemo();
// Calling method
demo.demonstrateSyntax();
// Array declaration and initialization
int[] numbers = {1, 2, 3, 4, 5};
// Enhanced for loop (for-each)
System.out.println("Array elements:");
for (int num : numbers) {
System.out.print(num + " ");
}
System.out.println();
// Using constants
double radius = 5.0;
double area = PI * radius * radius;
System.out.println("Area of circle: " + area);
}
}
03. π¦ Data Types & Variables
Java is a strongly typed language, meaning every variable must be declared with a specific data type. Java has two categories of data types: primitive and reference types.
Primitive Data Types
- byte: 8-bit integer (-128 to 127)
- short: 16-bit integer (-32,768 to 32,767)
- int: 32-bit integer (most common)
- long: 64-bit integer
- float: 32-bit floating point
- double: 64-bit floating point (default)
- char: 16-bit Unicode character
- boolean: true or false
Reference Data Types
Reference types store references (addresses) to objects:
1. Classes: String, Scanner, etc.
2. Arrays: int[], String[], etc.
3. Interfaces: Runnable, List, etc.
4. Enums: Special class types
Example: Data Types and Variables
public class DataTypesDemo {
public static void main(String[] args) {
// Primitive data types
byte smallNumber = 100; // 8-bit integer
short mediumNumber = 30000; // 16-bit integer
int regularNumber = 1000000; // 32-bit integer (most common)
long largeNumber = 10000000000L; // 64-bit integer (note L suffix)
float singlePrecision = 3.14f; // 32-bit float (note f suffix)
double doublePrecision = 3.141592653589793; // 64-bit double (default)
char letter = 'A'; // Single character
char unicodeChar = '\u0041'; // Unicode character 'A'
boolean isJavaFun = true; // true or false
// Display primitive types
System.out.println("=== Primitive Data Types ===");
System.out.println("byte: " + smallNumber);
System.out.println("short: " + mediumNumber);
System.out.println("int: " + regularNumber);
System.out.println("long: " + largeNumber);
System.out.println("float: " + singlePrecision);
System.out.println("double: " + doublePrecision);
System.out.println("char: " + letter);
System.out.println("boolean: " + isJavaFun);
// Reference data types
String message = "Hello, Java!"; // String object
int[] numbers = {1, 2, 3, 4, 5}; // Array object
// Display reference types
System.out.println("\n=== Reference Data Types ===");
System.out.println("String: " + message);
System.out.print("Array: ");
for (int num : numbers) {
System.out.print(num + " ");
}
System.out.println();
// Type casting
System.out.println("\n=== Type Casting ===");
// Widening casting (automatic)
int intValue = 100;
double doubleValue = intValue; // Automatic: int to double
System.out.println("int to double: " + intValue + " -> " + doubleValue);
// Narrowing casting (manual)
double price = 19.99;
int intPrice = (int) price; // Manual: double to int
System.out.println("double to int: " + price + " -> " + intPrice);
// Overflow example
byte maxByte = 127;
byte overflow = (byte) (maxByte + 1);
System.out.println("Byte overflow: 127 + 1 = " + overflow);
// Type promotion in expressions
System.out.println("\n=== Type Promotion ===");
byte b = 10;
short s = 20;
int i = 30;
long l = 40L;
float f = 50.0f;
double d = 60.0;
// Result is promoted to the largest type in expression
double result = b + s + i + l + f + d;
System.out.println("Promoted result: " + result);
// Wrapper classes (autoboxing/unboxing)
System.out.println("\n=== Wrapper Classes ===");
Integer wrappedInt = 42; // Autoboxing: int to Integer
int primitiveInt = wrappedInt; // Unboxing: Integer to int
System.out.println("Wrapped Integer: " + wrappedInt);
System.out.println("Primitive int: " + primitiveInt);
// Useful wrapper class methods
System.out.println("Max int value: " + Integer.MAX_VALUE);
System.out.println("Min int value: " + Integer.MIN_VALUE);
System.out.println("Integer to binary: " + Integer.toBinaryString(42));
System.out.println("Parse string to int: " + Integer.parseInt("123"));
// Constants
final double PI = 3.14159;
final int DAYS_IN_WEEK = 7;
System.out.println("\n=== Constants ===");
System.out.println("PI: " + PI);
System.out.println("Days in week: " + DAYS_IN_WEEK);
// PI = 3.14; // This would cause error - cannot reassign final variable
}
}
04. β Operators & Control Flow
Java provides a rich set of operators for performing operations on variables and values. Control flow statements determine the execution order of program statements.
Java Operator Categories
- Arithmetic: +, -, *, /, %, ++, --
- Assignment: =, +=, -=, *=, /=, %=
- Comparison: ==, !=, >, <, >=, <=
- Logical: &&, ||, !
- Bitwise: &, |, ^, ~, <<, >>, >>>
- Ternary: ? : (conditional operator)
- Instanceof: Type comparison operator
Control Flow Statements
Java provides several control flow mechanisms:
1. Conditional: if, if-else, switch
2. Looping: for, while, do-while, for-each
3. Branching: break, continue, return
4. Exception: try, catch, finally, throw
Example: Operators and Control Flow
public class OperatorsControlFlow {
public static void main(String[] args) {
System.out.println("=== ARITHMETIC OPERATORS ===");
int a = 10, b = 3;
System.out.println("a = " + a + ", b = " + b);
System.out.println("Addition (a + b): " + (a + b));
System.out.println("Subtraction (a - b): " + (a - b));
System.out.println("Multiplication (a * b): " + (a * b));
System.out.println("Division (a / b): " + (a / b));
System.out.println("Modulus (a % b): " + (a % b));
// Increment/Decrement
int x = 5;
System.out.println("\nPost-increment (x++): " + x++); // Prints 5, then x becomes 6
System.out.println("After post-increment: " + x);
System.out.println("Pre-increment (++x): " + ++x); // x becomes 7, then prints 7
System.out.println("\n=== ASSIGNMENT OPERATORS ===");
int num = 10;
num += 5; // num = num + 5
System.out.println("num += 5: " + num);
num *= 2; // num = num * 2
System.out.println("num *= 2: " + num);
System.out.println("\n=== COMPARISON OPERATORS ===");
int p = 10, q = 20;
System.out.println("p == q: " + (p == q));
System.out.println("p != q: " + (p != q));
System.out.println("p > q: " + (p > q));
System.out.println("p < q: " + (p < q));
System.out.println("p >= 10: " + (p >= 10));
System.out.println("\n=== LOGICAL OPERATORS ===");
boolean isJavaFun = true;
boolean isProgrammingHard = false;
System.out.println("isJavaFun && isProgrammingHard: " +
(isJavaFun && isProgrammingHard));
System.out.println("isJavaFun || isProgrammingHard: " +
(isJavaFun || isProgrammingHard));
System.out.println("!isProgrammingHard: " + (!isProgrammingHard));
// Short-circuit evaluation
System.out.println("\n=== SHORT-CIRCUIT EVALUATION ===");
int count = 0;
if (count != 0 && 10 / count > 2) {
System.out.println("This won't execute (short-circuit)");
}
System.out.println("\n=== TERNARY OPERATOR ===");
int age = 18;
String canVote = (age >= 18) ? "Yes" : "No";
System.out.println("Age " + age + " can vote? " + canVote);
System.out.println("\n=== CONTROL FLOW: IF-ELSE ===");
int score = 85;
if (score >= 90) {
System.out.println("Grade: A");
} else if (score >= 80) {
System.out.println("Grade: B");
} else if (score >= 70) {
System.out.println("Grade: C");
} else {
System.out.println("Grade: F");
}
System.out.println("\n=== CONTROL FLOW: SWITCH ===");
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;
default:
System.out.println("Weekend");
}
// Switch expression (Java 14+)
String dayType = switch (day) {
case 1, 2, 3, 4, 5 -> "Weekday";
case 6, 7 -> "Weekend";
default -> "Invalid day";
};
System.out.println("Day type: " + dayType);
System.out.println("\n=== CONTROL FLOW: LOOPS ===");
// For loop
System.out.print("For loop (1-5): ");
for (int i = 1; i <= 5; i++) {
System.out.print(i + " ");
}
System.out.println();
// While loop
System.out.print("While loop (5-1): ");
int j = 5;
while (j >= 1) {
System.out.print(j + " ");
j--;
}
System.out.println();
// Do-while loop
System.out.print("Do-while loop (executes at least once): ");
int k = 0;
do {
System.out.print(k + " ");
k++;
} while (k < 3);
System.out.println();
// For-each loop (enhanced for loop)
System.out.print("For-each loop (array elements): ");
int[] numbers = {10, 20, 30, 40, 50};
for (int number : numbers) {
System.out.print(number + " ");
}
System.out.println();
System.out.println("\n=== CONTROL FLOW: BREAK & CONTINUE ===");
// Break example
System.out.print("Break at 3: ");
for (int i = 1; i <= 5; i++) {
if (i == 3) {
break; // Exit loop
}
System.out.print(i + " ");
}
System.out.println();
// Continue example
System.out.print("Continue (skip 3): ");
for (int i = 1; i <= 5; i++) {
if (i == 3) {
continue; // Skip iteration
}
System.out.print(i + " ");
}
System.out.println();
// Labeled break (rarely used)
System.out.println("\n=== LABELED BREAK ===");
outerLoop:
for (int i = 1; i <= 3; i++) {
for (int m = 1; m <= 3; m++) {
System.out.println("i=" + i + ", m=" + m);
if (i == 2 && m == 2) {
break outerLoop; // Break out of both loops
}
}
}
System.out.println("\n=== BITWISE OPERATORS ===");
int bitA = 5; // Binary: 0101
int bitB = 3; // Binary: 0011
System.out.println("bitA & bitB (AND): " + (bitA & bitB)); // 0001 = 1
System.out.println("bitA | bitB (OR): " + (bitA | bitB)); // 0111 = 7
System.out.println("bitA ^ bitB (XOR): " + (bitA ^ bitB)); // 0110 = 6
System.out.println("~bitA (NOT): " + (~bitA)); // ...11111010 = -6
System.out.println("bitA << 1 (Left shift): " + (bitA << 1)); // 1010 = 10
System.out.println("bitA >> 1 (Right shift): " + (bitA >> 1)); // 0010 = 2
System.out.println("\n=== INSTANCEOF OPERATOR ===");
String text = "Hello";
System.out.println("text instanceof String: " + (text instanceof String));
System.out.println("text instanceof Object: " + (text instanceof Object));
}
}
05. ποΈ Arrays & Strings
Arrays are collections of elements of the same type, while Strings are sequences of characters. Both are fundamental data structures in Java.
Array Characteristics
- Fixed Size: Length cannot be changed after creation
- Indexed Access: Elements accessed via index (0 to length-1)
- Contiguous Memory: Elements stored sequentially
- Type Safety: All elements must be same type
- Multi-dimensional: Arrays of arrays (2D, 3D, etc.)
String Features
Strings in Java are:
1. Immutable: Cannot be changed after creation
2. Interned: String pool for memory efficiency
3. Unicode Support: Full UTF-16 character set
4. Rich API: Many built-in methods for manipulation
Example: Arrays and Strings
import java.util.Arrays;
public class ArraysStringsDemo {
public static void main(String[] args) {
System.out.println("=== ARRAY DECLARATION & INITIALIZATION ===");
// Different ways to declare and initialize arrays
int[] numbers1 = new int[5]; // Declaration with size
int[] numbers2 = {1, 2, 3, 4, 5}; // Declaration with initialization
int[] numbers3 = new int[]{10, 20, 30}; // Full syntax
// Default values
System.out.println("Default int array values:");
for (int i = 0; i < numbers1.length; i++) {
System.out.print(numbers1[i] + " "); // All zeros
}
System.out.println();
// Accessing and modifying
numbers1[0] = 100;
numbers1[1] = 200;
System.out.println("After modification: " + numbers1[0] + ", " + numbers1[1]);
System.out.println("\n=== ARRAY TRAVERSAL ===");
// Traditional for loop
System.out.print("Traditional for loop: ");
for (int i = 0; i < numbers2.length; i++) {
System.out.print(numbers2[i] + " ");
}
System.out.println();
// Enhanced for loop (for-each)
System.out.print("Enhanced for loop: ");
for (int num : numbers2) {
System.out.print(num + " ");
}
System.out.println();
// Using Arrays.toString()
System.out.println("Arrays.toString(): " + Arrays.toString(numbers2));
System.out.println("\n=== MULTI-DIMENSIONAL ARRAYS ===");
// 2D array declaration
int[][] matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
// Traversing 2D array
System.out.println("2D Array:");
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();
}
// Jagged array (arrays of different lengths)
int[][] jagged = {
{1, 2},
{3, 4, 5},
{6, 7, 8, 9}
};
System.out.println("\nJagged Array:");
for (int[] row : jagged) {
for (int val : row) {
System.out.print(val + " ");
}
System.out.println();
}
System.out.println("\n=== ARRAY METHODS ===");
// Arrays class utility methods
int[] arr = {5, 2, 8, 1, 9};
// Sorting
Arrays.sort(arr);
System.out.println("Sorted array: " + Arrays.toString(arr));
// Searching
int index = Arrays.binarySearch(arr, 8);
System.out.println("Index of 8: " + index);
// Copying
int[] copy = Arrays.copyOf(arr, 3);
System.out.println("Copy of first 3 elements: " + Arrays.toString(copy));
// Filling
int[] filled = new int[5];
Arrays.fill(filled, 7);
System.out.println("Filled array: " + Arrays.toString(filled));
// Comparing
int[] arr1 = {1, 2, 3};
int[] arr2 = {1, 2, 3};
System.out.println("Arrays equal? " + Arrays.equals(arr1, arr2));
System.out.println("\n=== STRING BASICS ===");
// String creation
String str1 = "Hello"; // String literal (goes to string pool)
String str2 = new String("Hello"); // String object (heap)
String str3 = "Hello";
System.out.println("str1 == str2: " + (str1 == str2)); // false (different references)
System.out.println("str1 == str3: " + (str1 == str3)); // true (same reference in pool)
System.out.println("str1.equals(str2): " + str1.equals(str2)); // true (same content)
System.out.println("\n=== STRING METHODS ===");
String text = " Java Programming ";
// Length and character access
System.out.println("Original: '" + text + "'");
System.out.println("Length: " + text.length());
System.out.println("Char at index 5: " + text.charAt(5));
// Trimming and case
System.out.println("Trimmed: '" + text.trim() + "'");
System.out.println("Uppercase: " + text.toUpperCase());
System.out.println("Lowercase: " + text.toLowerCase());
// Substring
System.out.println("Substring(2, 6): " + text.substring(2, 6));
// Searching
System.out.println("Contains 'Java': " + text.contains("Java"));
System.out.println("Index of 'Pro': " + text.indexOf("Pro"));
System.out.println("Starts with 'Java': " + text.startsWith("Java"));
System.out.println("Ends with 'ing': " + text.endsWith("ing"));
// Replacement
System.out.println("Replace 'Java' with 'Python': " + text.replace("Java", "Python"));
// Splitting
String csv = "Apple,Banana,Cherry";
String[] fruits = csv.split(",");
System.out.println("Split fruits: " + Arrays.toString(fruits));
// Joining (Java 8+)
String joined = String.join(" - ", fruits);
System.out.println("Joined: " + joined);
// Comparison
String s1 = "apple";
String s2 = "banana";
System.out.println("Compare 'apple' to 'banana': " + s1.compareTo(s2));
System.out.println("Compare ignoring case: " + s1.compareToIgnoreCase("APPLE"));
System.out.println("\n=== STRING BUILDER (MUTABLE) ===");
// StringBuilder - mutable, efficient for concatenation
StringBuilder sb = new StringBuilder();
sb.append("Hello");
sb.append(" ");
sb.append("World");
sb.insert(5, ",");
sb.replace(0, 5, "Hi");
sb.delete(2, 4);
sb.reverse();
System.out.println("StringBuilder operations: " + sb.toString());
System.out.println("Capacity: " + sb.capacity());
System.out.println("Length: " + sb.length());
// Convert back to String
String result = sb.toString();
System.out.println("\n=== STRING FORMATTING ===");
// String formatting
String name = "Alice";
int age = 25;
double salary = 50000.50;
String formatted = String.format("Name: %s, Age: %d, Salary: $%,.2f", name, age, salary);
System.out.println(formatted);
// printf style
System.out.printf("Name: %s, Age: %d, Salary: $%,.2f%n", name, age, salary);
System.out.println("\n=== STRING POOL DEMONSTRATION ===");
// String pool demonstration
String a = "hello";
String b = "hello";
String c = new String("hello");
String d = c.intern();
System.out.println("a == b: " + (a == b)); // true (both in pool)
System.out.println("a == c: " + (a == c)); // false (c is new object)
System.out.println("a == d: " + (a == d)); // true (d is interned)
System.out.println("\n=== CHARACTER ARRAY CONVERSION ===");
// String to char array and vice versa
String word = "Java";
char[] chars = word.toCharArray();
System.out.print("Character array: ");
for (char ch : chars) {
System.out.print(ch + " ");
}
System.out.println();
String fromChars = new String(chars);
System.out.println("Back to string: " + fromChars);
}
}
06. ποΈ Object-Oriented Programming
Java is a pure object-oriented programming language where everything is an object (except primitive types). OOP organizes software design around objects rather than functions and logic.
Four Pillars of OOP
- Encapsulation: Bundling data with methods that operate on that data
- Abstraction: Hiding complex implementation details
- Inheritance: Creating new classes from existing ones
- Polymorphism: Objects of different types can be accessed through the same interface
Classes and Objects
Class: Blueprint/template for creating objects
Object: Instance of a class with state and behavior
Constructor: Special method to initialize objects
Methods: Functions that define object behavior
Fields: Variables that define object state
Example: OOP Concepts in Java
// ========== ENCAPSULATION ==========
class BankAccount {
// Private fields (data hiding)
private String accountNumber;
private String accountHolder;
private double balance;
// Constructor
public BankAccount(String accountNumber, String accountHolder, double initialBalance) {
this.accountNumber = accountNumber;
this.accountHolder = accountHolder;
this.balance = initialBalance;
}
// Getter methods (accessors)
public String getAccountNumber() {
return accountNumber;
}
public String getAccountHolder() {
return accountHolder;
}
public double getBalance() {
return balance;
}
// Setter methods (mutators) with validation
public void setAccountHolder(String accountHolder) {
if (accountHolder != null && !accountHolder.isEmpty()) {
this.accountHolder = accountHolder;
}
}
// Business logic methods
public void deposit(double amount) {
if (amount > 0) {
balance += amount;
System.out.println("Deposited: $" + amount);
}
}
public void withdraw(double amount) {
if (amount > 0 && amount <= balance) {
balance -= amount;
System.out.println("Withdrawn: $" + amount);
} else {
System.out.println("Insufficient funds or invalid amount");
}
}
// Display account info
public void displayAccountInfo() {
System.out.println("Account: " + accountNumber);
System.out.println("Holder: " + accountHolder);
System.out.println("Balance: $" + balance);
}
}
// ========== ABSTRACTION ==========
abstract class Vehicle {
// Abstract method (no implementation)
public abstract void start();
public abstract void stop();
// Concrete method
public void honk() {
System.out.println("Beep beep!");
}
}
class Car extends Vehicle {
@Override
public void start() {
System.out.println("Car starting... Vroom!");
}
@Override
public void stop() {
System.out.println("Car stopping... Screech!");
}
}
// Interface (pure abstraction)
interface ElectricVehicle {
void charge();
int getBatteryLevel();
}
// ========== INHERITANCE ==========
// Base class
class Employee {
protected String name;
protected int id;
protected double salary;
public Employee(String name, int id, double salary) {
this.name = name;
this.id = id;
this.salary = salary;
}
public void work() {
System.out.println(name + " is working");
}
public void displayInfo() {
System.out.println("ID: " + id + ", Name: " + name + ", Salary: $" + salary);
}
}
// Derived class
class Manager extends Employee {
private String department;
private int teamSize;
public Manager(String name, int id, double salary, String department, int teamSize) {
super(name, id, salary); // Call parent constructor
this.department = department;
this.teamSize = teamSize;
}
// Additional method
public void conductMeeting() {
System.out.println(name + " is conducting a meeting with " + teamSize + " team members");
}
// Method overriding
@Override
public void displayInfo() {
super.displayInfo();
System.out.println("Department: " + department + ", Team Size: " + teamSize);
}
}
// ========== POLYMORPHISM ==========
interface Shape {
double calculateArea();
double calculatePerimeter();
}
class Circle implements Shape {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
public double calculateArea() {
return Math.PI * radius * radius;
}
@Override
public double calculatePerimeter() {
return 2 * Math.PI * radius;
}
}
class Rectangle implements Shape {
private double width;
private double height;
public Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
@Override
public double calculateArea() {
return width * height;
}
@Override
public double calculatePerimeter() {
return 2 * (width + height);
}
}
// ========== MAIN CLASS ==========
public class OOPDemo {
public static void main(String[] args) {
System.out.println("=== ENCAPSULATION DEMO ===");
BankAccount account = new BankAccount("123456", "John Doe", 1000.0);
account.displayAccountInfo();
account.deposit(500);
account.withdraw(200);
account.displayAccountInfo();
System.out.println("\n=== ABSTRACTION DEMO ===");
Vehicle myCar = new Car();
myCar.start();
myCar.honk();
myCar.stop();
System.out.println("\n=== INHERITANCE DEMO ===");
Employee emp = new Employee("Alice", 101, 50000);
emp.work();
emp.displayInfo();
Manager mgr = new Manager("Bob", 102, 75000, "Engineering", 5);
mgr.work();
mgr.conductMeeting();
mgr.displayInfo();
// Polymorphism through inheritance
Employee emp2 = new Manager("Charlie", 103, 80000, "Sales", 3);
emp2.displayInfo(); // Calls Manager's overridden method
System.out.println("\n=== POLYMORPHISM DEMO ===");
Shape[] shapes = new Shape[2];
shapes[0] = new Circle(5.0);
shapes[1] = new Rectangle(4.0, 6.0);
for (Shape shape : shapes) {
System.out.println("Area: " + shape.calculateArea());
System.out.println("Perimeter: " + shape.calculatePerimeter());
System.out.println();
}
System.out.println("=== STATIC VS INSTANCE ===");
Counter c1 = new Counter();
Counter c2 = new Counter();
c1.increment();
c2.increment();
c2.increment();
System.out.println("c1 count: " + c1.getCount());
System.out.println("c2 count: " + c2.getCount());
System.out.println("Total count (static): " + Counter.getTotalCount());
System.out.println("\n=== THIS KEYWORD DEMO ===");
Person person = new Person("John", 25);
person.display();
System.out.println("\n=== FINAL KEYWORD ===");
final int MAX_VALUE = 100;
System.out.println("Final constant: " + MAX_VALUE);
final Person finalPerson = new Person("Jane", 30);
// finalPerson = new Person("New", 40); // Error: cannot reassign
finalPerson.setAge(31); // OK: can modify object state
System.out.println("\n=== ACCESS MODIFIERS ===");
AccessDemo demo = new AccessDemo();
// demo.privateVar = 10; // Error: private
demo.publicVar = 20; // OK: public
demo.protectedVar = 30; // OK: same package
demo.defaultVar = 40; // OK: same package
System.out.println("\n=== METHOD OVERLOADING ===");
Calculator calc = new Calculator();
System.out.println("Add ints: " + calc.add(5, 3));
System.out.println("Add doubles: " + calc.add(5.5, 3.3));
System.out.println("Add three: " + calc.add(1, 2, 3));
System.out.println("Add strings: " + calc.add("Hello", "World"));
}
}
// ========== ADDITIONAL DEMO CLASSES ==========
// Static vs instance demonstration
class Counter {
private int count = 0; // Instance variable
private static int totalCount = 0; // Class variable
public void increment() {
count++;
totalCount++;
}
public int getCount() {
return count;
}
public static int getTotalCount() {
return totalCount;
}
}
// This keyword demonstration
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name; // 'this' refers to current instance
this.age = age;
}
public void setAge(int age) {
this.age = age; // Parameter shadows instance variable
}
public void display() {
System.out.println("Name: " + this.name + ", Age: " + this.age);
}
}
// Access modifiers
class AccessDemo {
private int privateVar = 1; // Only within class
public int publicVar = 2; // Accessible anywhere
protected int protectedVar = 3; // Within package + subclasses
int defaultVar = 4; // Within package only (default/package-private)
}
// Method overloading
class Calculator {
// Same method name, different parameters
public int add(int a, int b) {
return a + b;
}
public double add(double a, double b) {
return a + b;
}
public int add(int a, int b, int c) {
return a + b + c;
}
public String add(String a, String b) {
return a + " " + b;
}
}
07. π³ Inheritance & Polymorphism
Inheritance allows a class to inherit properties and methods from another class. Polymorphism enables objects of different classes to be treated as objects of a common super class.
Types of Inheritance in Java
- Single Inheritance: One class extends another
- Multilevel Inheritance: Chain of inheritance
- Hierarchical Inheritance: Multiple classes extend one class
- Multiple Inheritance: Not supported (use interfaces)
- Hybrid Inheritance: Combination (via interfaces)
Polymorphism Types
1. Compile-time Polymorphism: Method overloading
2. Runtime Polymorphism: Method overriding
3. Interface Polymorphism: Implementing interfaces
4. Abstract Class Polymorphism: Extending abstract classes
Example: Inheritance and Polymorphism
// ========== INHERITANCE HIERARCHY ==========
// Base class
class Animal {
protected String name;
protected int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public void eat() {
System.out.println(name + " is eating");
}
public void sleep() {
System.out.println(name + " is sleeping");
}
public void makeSound() {
System.out.println(name + " makes a generic sound");
}
public void displayInfo() {
System.out.println("Animal: " + name + ", Age: " + age);
}
}
// Single inheritance
class Mammal extends Animal {
protected boolean hasFur;
protected String habitat;
public Mammal(String name, int age, boolean hasFur, String habitat) {
super(name, age); // Call parent constructor
this.hasFur = hasFur;
this.habitat = habitat;
}
// Additional method
public void giveBirth() {
System.out.println(name + " gives birth to live young");
}
// Method overriding
@Override
public void makeSound() {
System.out.println(name + " makes mammal sound");
}
@Override
public void displayInfo() {
super.displayInfo();
System.out.println("Type: Mammal, Has Fur: " + hasFur + ", Habitat: " + habitat);
}
}
// Multilevel inheritance
class Dog extends Mammal {
private String breed;
private boolean isTrained;
public Dog(String name, int age, String breed, boolean isTrained) {
super(name, age, true, "Domestic"); // Call Mammal constructor
this.breed = breed;
this.isTrained = isTrained;
}
// Additional methods
public void bark() {
System.out.println(name + " barks: Woof! Woof!");
}
public void fetch() {
System.out.println(name + " fetches the ball");
}
// Override parent method
@Override
public void makeSound() {
bark();
}
@Override
public void displayInfo() {
super.displayInfo();
System.out.println("Breed: " + breed + ", Trained: " + isTrained);
}
}
// Hierarchical inheritance
class Cat extends Mammal {
private String color;
private boolean isIndoor;
public Cat(String name, int age, String color, boolean isIndoor) {
super(name, age, true, "Domestic");
this.color = color;
this.isIndoor = isIndoor;
}
public void meow() {
System.out.println(name + " meows: Meow!");
}
public void purr() {
System.out.println(name + " purrs: Purrr...");
}
@Override
public void makeSound() {
meow();
}
@Override
public void displayInfo() {
super.displayInfo();
System.out.println("Color: " + color + ", Indoor: " + isIndoor);
}
}
// Bird class (another hierarchical example)
class Bird extends Animal {
protected boolean canFly;
protected double wingspan;
public Bird(String name, int age, boolean canFly, double wingspan) {
super(name, age);
this.canFly = canFly;
this.wingspan = wingspan;
}
public void fly() {
if (canFly) {
System.out.println(name + " is flying");
} else {
System.out.println(name + " cannot fly");
}
}
@Override
public void makeSound() {
System.out.println(name + " chirps");
}
@Override
public void displayInfo() {
super.displayInfo();
System.out.println("Type: Bird, Can Fly: " + canFly + ", Wingspan: " + wingspan + "m");
}
}
// ========== POLYMORPHISM DEMONSTRATION ==========
// Abstract class for polymorphism
abstract class Employee {
protected String name;
protected double salary;
public Employee(String name, double salary) {
this.name = name;
this.salary = salary;
}
// Abstract method (must be implemented by subclasses)
public abstract void work();
// Concrete method
public void takeBreak() {
System.out.println(name + " is taking a break");
}
// Can be overridden
public void displayInfo() {
System.out.println("Name: " + name + ", Salary: $" + salary);
}
}
class Developer extends Employee {
private String programmingLanguage;
public Developer(String name, double salary, String programmingLanguage) {
super(name, salary);
this.programmingLanguage = programmingLanguage;
}
@Override
public void work() {
System.out.println(name + " is writing code in " + programmingLanguage);
}
@Override
public void displayInfo() {
super.displayInfo();
System.out.println("Role: Developer, Language: " + programmingLanguage);
}
}
class Manager extends Employee {
private int teamSize;
public Manager(String name, double salary, int teamSize) {
super(name, salary);
this.teamSize = teamSize;
}
@Override
public void work() {
System.out.println(name + " is managing a team of " + teamSize + " people");
}
@Override
public void displayInfo() {
super.displayInfo();
System.out.println("Role: Manager, Team Size: " + teamSize);
}
}
// Interface for multiple inheritance simulation
interface Swimmable {
void swim();
int getSwimSpeed();
}
interface Flyable {
void fly();
int getFlightSpeed();
}
// Class implementing multiple interfaces
class Duck extends Animal implements Swimmable, Flyable {
public Duck(String name, int age) {
super(name, age);
}
@Override
public void swim() {
System.out.println(name + " is swimming");
}
@Override
public int getSwimSpeed() {
return 5; // km/h
}
@Override
public void fly() {
System.out.println(name + " is flying");
}
@Override
public int getFlightSpeed() {
return 80; // km/h
}
@Override
public void makeSound() {
System.out.println(name + " quacks");
}
@Override
public void displayInfo() {
super.displayInfo();
System.out.println("Type: Duck, Swim Speed: " + getSwimSpeed() + " km/h, Flight Speed: " + getFlightSpeed() + " km/h");
}
}
// ========== MAIN CLASS ==========
public class InheritancePolymorphismDemo {
public static void main(String[] args) {
System.out.println("=== SINGLE INHERITANCE ===");
Mammal mammal = new Mammal("Bear", 5, true, "Forest");
mammal.displayInfo();
mammal.makeSound();
mammal.giveBirth();
System.out.println("\n=== MULTILEVEL INHERITANCE ===");
Dog dog = new Dog("Buddy", 3, "Golden Retriever", true);
dog.displayInfo();
dog.makeSound();
dog.fetch();
System.out.println("\n=== HIERARCHICAL INHERITANCE ===");
Cat cat = new Cat("Whiskers", 2, "Tabby", true);
Bird bird = new Bird("Tweety", 1, true, 0.5);
cat.displayInfo();
cat.makeSound();
cat.purr();
System.out.println();
bird.displayInfo();
bird.makeSound();
bird.fly();
System.out.println("\n=== RUNTIME POLYMORPHISM ===");
// Upcasting
Animal myPet1 = new Dog("Max", 4, "German Shepherd", false);
Animal myPet2 = new Cat("Luna", 1, "Black", true);
Animal myPet3 = new Bird("Polly", 2, true, 0.3);
// All treated as Animals, but execute their own methods
Animal[] animals = {myPet1, myPet2, myPet3};
for (Animal animal : animals) {
animal.makeSound(); // Polymorphic call
System.out.println();
}
System.out.println("=== ABSTRACT CLASS POLYMORPHISM ===");
Employee emp1 = new Developer("Alice", 75000, "Java");
Employee emp2 = new Manager("Bob", 90000, 5);
Employee[] employees = {emp1, emp2};
for (Employee emp : employees) {
emp.displayInfo();
emp.work();
emp.takeBreak();
System.out.println();
}
System.out.println("=== INTERFACE POLYMORPHISM ===");
Duck duck = new Duck("Donald", 3);
duck.displayInfo();
duck.swim();
duck.fly();
duck.makeSound();
// Treating as interfaces
Swimmable swimmer = duck;
Flyable flyer = duck;
swimmer.swim();
System.out.println("Swim speed: " + swimmer.getSwimSpeed() + " km/h");
flyer.fly();
System.out.println("Flight speed: " + flyer.getFlightSpeed() + " km/h");
System.out.println("\n=== METHOD OVERLOADING (COMPILE-TIME POLYMORPHISM) ===");
MathOperations math = new MathOperations();
System.out.println("Add ints: " + math.add(5, 3));
System.out.println("Add doubles: " + math.add(5.5, 3.3));
System.out.println("Add three: " + math.add(1, 2, 3));
System.out.println("Add array: " + math.add(new int[]{1, 2, 3, 4, 5}));
System.out.println("\n=== SUPER KEYWORD USAGE ===");
Child child = new Child();
child.display();
System.out.println("\n=== FINAL CLASS AND METHODS ===");
FinalDemo demo = new FinalDemo();
demo.display();
// Cannot extend FinalClass
}
}
// ========== ADDITIONAL CLASSES ==========
// Method overloading example
class MathOperations {
// Overloaded methods
public int add(int a, int b) {
return a + b;
}
public double add(double a, double b) {
return a + b;
}
public int add(int a, int b, int c) {
return a + b + c;
}
public int add(int[] numbers) {
int sum = 0;
for (int num : numbers) {
sum += num;
}
return sum;
}
}
// Super keyword demonstration
class Parent {
protected String message = "Parent message";
public void show() {
System.out.println("Parent show() method");
}
}
class Child extends Parent {
private String message = "Child message";
public void display() {
System.out.println("Child message: " + message);
System.out.println("Parent message: " + super.message); // Access parent field
show(); // Calls Child's show() if overridden
super.show(); // Always calls Parent's show()
}
@Override
public void show() {
System.out.println("Child show() method");
}
}
// Final keyword
final class FinalClass {
public void display() {
System.out.println("This is a final class");
}
}
class FinalDemo extends FinalClass { // Error: cannot extend final class
// Cannot override final methods
@Override
public void display() {
System.out.println("Trying to override");
}
}
08. β οΈ Exception Handling
Exception handling is a mechanism to handle runtime errors so that normal flow of the application can be maintained. Java provides a robust exception handling framework.
Exception Hierarchy
- Throwable: Root class of exception hierarchy
- Error: Serious problems (out of memory, stack overflow)
- Exception: Problems that can be handled
- RuntimeException: Unchecked exceptions (NullPointerException)
- Checked Exceptions: Must be handled or declared (IOException)
Exception Handling Keywords
1. try: Block of code to monitor for exceptions
2. catch: Block to handle specific exceptions
3. finally: Block that always executes (cleanup)
4. throw: To explicitly throw an exception
5. throws: Declares exceptions a method might throw
Example: Exception Handling in Java
import java.io.*;
import java.util.*;
public class ExceptionHandlingDemo {
// ========== BASIC EXCEPTION HANDLING ==========
public static void basicExceptionDemo() {
System.out.println("=== BASIC EXCEPTION HANDLING ===");
try {
// Code that might throw an exception
int[] numbers = {1, 2, 3};
System.out.println("Accessing element at index 5: " + numbers[5]); // ArrayIndexOutOfBoundsException
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Exception caught: " + e.getMessage());
System.out.println("Stack trace:");
e.printStackTrace();
}
System.out.println("Program continues after exception handling");
}
// ========== MULTIPLE CATCH BLOCKS ==========
public static void multipleCatchDemo() {
System.out.println("\n=== MULTIPLE CATCH BLOCKS ===");
Scanner scanner = new Scanner(System.in);
try {
System.out.print("Enter numerator: ");
int numerator = scanner.nextInt();
System.out.print("Enter denominator: ");
int denominator = scanner.nextInt();
int result = numerator / denominator; // Might throw ArithmeticException
System.out.println("Result: " + result);
String text = null;
System.out.println("Text length: " + text.length()); // Might throw NullPointerException
} catch (ArithmeticException e) {
System.out.println("Arithmetic error: Cannot divide by zero!");
} catch (NullPointerException e) {
System.out.println("Null pointer error: Object is null!");
} catch (InputMismatchException e) {
System.out.println("Input error: Please enter valid integers!");
scanner.nextLine(); // Clear invalid input
} catch (Exception e) {
System.out.println("Generic exception caught: " + e.getClass().getName());
} finally {
System.out.println("Finally block executed - cleanup code");
scanner.close();
}
}
// ========== CHECKED EXCEPTIONS ==========
public static void checkedExceptionDemo() throws IOException {
System.out.println("\n=== CHECKED EXCEPTIONS ===");
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader("test.txt"));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (FileNotFoundException e) {
System.out.println("File not found: " + e.getMessage());
throw new IOException("Custom error: File operation failed", e); // Re-throw
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
System.out.println("Error closing file: " + e.getMessage());
}
}
}
}
// ========== CUSTOM EXCEPTIONS ==========
static class InsufficientFundsException extends Exception {
private double amount;
private double balance;
public InsufficientFundsException(double amount, double balance) {
super("Insufficient funds: Attempted to withdraw $" + amount + " but balance is $" + balance);
this.amount = amount;
this.balance = balance;
}
public double getAmount() {
return amount;
}
public double getBalance() {
return balance;
}
}
static class InvalidAccountException extends RuntimeException {
public InvalidAccountException(String message) {
super(message);
}
}
static class BankAccount {
private double balance;
private String accountNumber;
public BankAccount(String accountNumber, double initialBalance) {
this.accountNumber = accountNumber;
this.balance = initialBalance;
}
public void withdraw(double amount) throws InsufficientFundsException {
if (amount > balance) {
throw new InsufficientFundsException(amount, balance);
}
balance -= amount;
System.out.println("Withdrawn: $" + amount + ", New balance: $" + balance);
}
public void transfer(BankAccount other, double amount) throws InsufficientFundsException {
if (other == null) {
throw new InvalidAccountException("Cannot transfer to null account");
}
this.withdraw(amount);
other.deposit(amount);
System.out.println("Transferred $" + amount + " to account " + other.accountNumber);
}
public void deposit(double amount) {
if (amount <= 0) {
throw new IllegalArgumentException("Deposit amount must be positive");
}
balance += amount;
}
}
public static void customExceptionDemo() {
System.out.println("\n=== CUSTOM EXCEPTIONS ===");
BankAccount account1 = new BankAccount("12345", 1000);
BankAccount account2 = new BankAccount("67890", 500);
try {
account1.withdraw(200);
account1.withdraw(1000); // This will throw exception
} catch (InsufficientFundsException e) {
System.out.println("Custom exception caught: " + e.getMessage());
System.out.println("Shortfall: $" + (e.getAmount() - e.getBalance()));
}
try {
account1.transfer(null, 100); // Will throw runtime exception
} catch (InvalidAccountException e) {
System.out.println("Runtime exception caught: " + e.getMessage());
}
try {
account2.deposit(-100); // Will throw IllegalArgumentException
} catch (IllegalArgumentException e) {
System.out.println("Illegal argument: " + e.getMessage());
}
}
// ========== TRY-WITH-RESOURCES ==========
public static void tryWithResourcesDemo() {
System.out.println("\n=== TRY-WITH-RESOURCES (Java 7+) ===");
// Auto-closable resources
try (BufferedReader reader = new BufferedReader(new StringReader("Line 1\nLine 2\nLine 3"));
BufferedWriter writer = new BufferedWriter(new StringWriter())) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println("Read: " + line);
writer.write("Processed: " + line);
writer.newLine();
}
System.out.println("Resources automatically closed");
} catch (IOException e) {
System.out.println("IO error: " + e.getMessage());
}
}
// ========== EXCEPTION PROPAGATION ==========
public static void methodA() throws IOException {
System.out.println("In methodA");
methodB();
}
public static void methodB() throws IOException {
System.out.println("In methodB");
throw new IOException("Error from methodB");
}
public static void exceptionPropagationDemo() {
System.out.println("\n=== EXCEPTION PROPAGATION ===");
try {
methodA();
} catch (IOException e) {
System.out.println("Caught in main: " + e.getMessage());
}
}
// ========== STACK TRACE MANIPULATION ==========
public static void stackTraceDemo() {
System.out.println("\n=== STACK TRACE MANIPULATION ===");
try {
throw new Exception("Test exception");
} catch (Exception e) {
System.out.println("Original stack trace:");
e.printStackTrace();
// Get stack trace elements
StackTraceElement[] stackTrace = e.getStackTrace();
System.out.println("\nStack trace elements:");
for (StackTraceElement element : stackTrace) {
System.out.println(" " + element.getClassName() + "." + element.getMethodName() +
" (Line " + element.getLineNumber() + ")");
}
// Create new exception with cause
Exception wrapped = new Exception("Wrapped exception", e);
System.out.println("\nWrapped exception cause: " + wrapped.getCause().getMessage());
}
}
// ========== MAIN METHOD ==========
public static void main(String[] args) {
// Basic exception handling
basicExceptionDemo();
// Multiple catch blocks
multipleCatchDemo();
// Custom exceptions
customExceptionDemo();
// Try-with-resources
tryWithResourcesDemo();
// Exception propagation
exceptionPropagationDemo();
// Stack trace manipulation
stackTraceDemo();
// Checked exceptions (handled in main)
try {
checkedExceptionDemo();
} catch (IOException e) {
System.out.println("Main caught: " + e.getMessage());
}
System.out.println("\n=== EXCEPTION BEST PRACTICES ===");
System.out.println("1. Catch specific exceptions first");
System.out.println("2. Don't catch Throwable or Exception unless necessary");
System.out.println("3. Clean up resources in finally blocks");
System.out.println("4. Use try-with-resources for AutoCloseable objects");
System.out.println("5. Don't suppress exceptions");
System.out.println("6. Include meaningful messages in custom exceptions");
System.out.println("7. Consider checked vs unchecked exceptions carefully");
}
}
// ========== ADDITIONAL EXCEPTION CLASSES ==========
// AutoCloseable resource
class DatabaseConnection implements AutoCloseable {
private String connectionId;
private boolean isOpen = true;
public DatabaseConnection(String connectionId) {
this.connectionId = connectionId;
System.out.println("Database connection " + connectionId + " opened");
}
public void executeQuery(String query) throws SQLException {
if (!isOpen) {
throw new SQLException("Connection closed");
}
System.out.println("Executing query: " + query);
// Simulate error
if (query.contains("DROP")) {
throw new SQLException("DROP not allowed");
}
}
@Override
public void close() {
isOpen = false;
System.out.println("Database connection " + connectionId + " closed");
}
}
// Simulated SQLException for demonstration
class SQLException extends Exception {
public SQLException(String message) {
super(message);
}
}
// Exception chaining example
class DataProcessor {
public void processData(String data) throws ProcessingException {
try {
// Some processing that might fail
if (data == null) {
throw new IllegalArgumentException("Data cannot be null");
}
int result = Integer.parseInt(data); // Might throw NumberFormatException
} catch (IllegalArgumentException | NumberFormatException e) {
// Chain exceptions
throw new ProcessingException("Failed to process data", e);
}
}
}
class ProcessingException extends Exception {
public ProcessingException(String message, Throwable cause) {
super(message, cause);
}
}
09. π Collections Framework
The Java Collections Framework provides a set of interfaces and classes for storing and manipulating groups of data as a single unit. It's one of the most important parts of Java.
Collection Interfaces
- Collection: Root interface (List, Set, Queue)
- List: Ordered collection with duplicates (ArrayList, LinkedList)
- Set: No duplicates (HashSet, TreeSet)
- Queue: FIFO order (PriorityQueue, LinkedList)
- Map: Key-value pairs (HashMap, TreeMap)
- SortedSet: Sorted set (TreeSet)
- SortedMap: Sorted map (TreeMap)
Key Collection Classes
Common implementations:
1. ArrayList: Resizable array, fast random access
2. LinkedList: Doubly-linked list, fast insert/delete
3. HashSet: Hash table implementation of Set
4. TreeSet: Red-black tree, sorted order
5. HashMap: Hash table implementation of Map
6. TreeMap: Red-black tree, sorted by keys
Example: Collections Framework
import java.util.*;
import java.util.stream.Collectors;
public class CollectionsFrameworkDemo {
public static void main(String[] args) {
System.out.println("=== LIST INTERFACE ===");
listDemo();
System.out.println("\n=== SET INTERFACE ===");
setDemo();
System.out.println("\n=== MAP INTERFACE ===");
mapDemo();
System.out.println("\n=== QUEUE INTERFACE ===");
queueDemo();
System.out.println("\n=== ITERATORS ===");
iteratorDemo();
System.out.println("\n=== COLLECTIONS UTILITY CLASS ===");
collectionsUtilityDemo();
System.out.println("\n=== COMPARABLE & COMPARATOR ===");
comparatorDemo();
System.out.println("\n=== JAVA 8+ STREAMS WITH COLLECTIONS ===");
streamsDemo();
}
// ========== LIST DEMONSTRATION ==========
static void listDemo() {
// ArrayList - most commonly used
List arrayList = new ArrayList<>();
arrayList.add("Apple");
arrayList.add("Banana");
arrayList.add("Cherry");
arrayList.add("Banana"); // Duplicates allowed
System.out.println("ArrayList: " + arrayList);
System.out.println("Size: " + arrayList.size());
System.out.println("Contains 'Apple': " + arrayList.contains("Apple"));
System.out.println("Element at index 1: " + arrayList.get(1));
// Modify
arrayList.set(1, "Blueberry");
arrayList.remove(2);
System.out.println("After modifications: " + arrayList);
// LinkedList - good for frequent insertions/deletions
List linkedList = new LinkedList<>();
linkedList.add(10);
linkedList.add(20);
linkedList.add(30);
linkedList.addFirst(5);
linkedList.addLast(40);
System.out.println("\nLinkedList: " + linkedList);
// Vector (thread-safe but slower)
List vector = new Vector<>();
vector.add("One");
vector.add("Two");
System.out.println("Vector: " + vector);
// Stack (LIFO)
Stack stack = new Stack<>();
stack.push("First");
stack.push("Second");
stack.push("Third");
System.out.println("Stack: " + stack);
System.out.println("Popped: " + stack.pop());
System.out.println("Peek: " + stack.peek());
System.out.println("Stack after pop: " + stack);
}
// ========== SET DEMONSTRATION ==========
static void setDemo() {
// HashSet - no order, no duplicates
Set hashSet = new HashSet<>();
hashSet.add("Apple");
hashSet.add("Banana");
hashSet.add("Cherry");
hashSet.add("Apple"); // Duplicate ignored
System.out.println("HashSet: " + hashSet);
System.out.println("Size: " + hashSet.size());
// LinkedHashSet - maintains insertion order
Set linkedHashSet = new LinkedHashSet<>();
linkedHashSet.add("Zebra");
linkedHashSet.add("Apple");
linkedHashSet.add("Banana");
System.out.println("LinkedHashSet (insertion order): " + linkedHashSet);
// TreeSet - sorted order
Set treeSet = new TreeSet<>();
treeSet.add("Zebra");
treeSet.add("Apple");
treeSet.add("Banana");
System.out.println("TreeSet (sorted): " + treeSet);
// TreeSet with custom comparator
Set treeSetReverse = new TreeSet<>(Collections.reverseOrder());
treeSetReverse.addAll(treeSet);
System.out.println("TreeSet (reverse order): " + treeSetReverse);
// Set operations
Set set1 = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5));
Set set2 = new HashSet<>(Arrays.asList(4, 5, 6, 7, 8));
// Union
Set union = new HashSet<>(set1);
union.addAll(set2);
System.out.println("Set1 βͺ Set2: " + union);
// Intersection
Set intersection = new HashSet<>(set1);
intersection.retainAll(set2);
System.out.println("Set1 β© Set2: " + intersection);
// Difference
Set difference = new HashSet<>(set1);
difference.removeAll(set2);
System.out.println("Set1 - Set2: " + difference);
}
// ========== MAP DEMONSTRATION ==========
static void mapDemo() {
// HashMap - most commonly used
Map hashMap = new HashMap<>();
hashMap.put("John", 25);
hashMap.put("Alice", 30);
hashMap.put("Bob", 28);
hashMap.put("John", 26); // Overwrites previous value
System.out.println("HashMap: " + hashMap);
System.out.println("Size: " + hashMap.size());
System.out.println("Get Alice's age: " + hashMap.get("Alice"));
System.out.println("Contains key 'Bob': " + hashMap.containsKey("Bob"));
System.out.println("Contains value 30: " + hashMap.containsValue(30));
// Iterating through map
System.out.println("\nIterating HashMap:");
for (Map.Entry entry : hashMap.entrySet()) {
System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue());
}
// LinkedHashMap - maintains insertion order
Map linkedHashMap = new LinkedHashMap<>();
linkedHashMap.put("Zebra", 5);
linkedHashMap.put("Apple", 3);
linkedHashMap.put("Banana", 2);
System.out.println("\nLinkedHashMap (insertion order): " + linkedHashMap);
// TreeMap - sorted by keys
Map treeMap = new TreeMap<>();
treeMap.put("Zebra", 5);
treeMap.put("Apple", 3);
treeMap.put("Banana", 2);
System.out.println("TreeMap (sorted keys): " + treeMap);
// TreeMap with custom comparator
Map treeMapReverse = new TreeMap<>(Collections.reverseOrder());
treeMapReverse.putAll(treeMap);
System.out.println("TreeMap (reverse order): " + treeMapReverse);
// Map operations
Map map1 = new HashMap<>();
map1.put("A", 1);
map1.put("B", 2);
Map map2 = new HashMap<>();
map2.put("B", 3);
map2.put("C", 4);
// Merge maps
Map merged = new HashMap<>(map1);
map2.forEach((key, value) ->
merged.merge(key, value, (v1, v2) -> v1 + v2));
System.out.println("\nMerged map (sum values on conflict): " + merged);
}
// ========== QUEUE DEMONSTRATION ==========
static void queueDemo() {
// LinkedList as Queue (FIFO)
Queue queue = new LinkedList<>();
queue.add("First");
queue.add("Second");
queue.add("Third");
System.out.println("Queue: " + queue);
System.out.println("Peek: " + queue.peek());
System.out.println("Poll: " + queue.poll());
System.out.println("Queue after poll: " + queue);
// PriorityQueue - natural ordering or custom comparator
Queue priorityQueue = new PriorityQueue<>();
priorityQueue.add(30);
priorityQueue.add(10);
priorityQueue.add(20);
System.out.println("\nPriorityQueue (natural order):");
while (!priorityQueue.isEmpty()) {
System.out.print(priorityQueue.poll() + " ");
}
System.out.println();
// PriorityQueue with custom comparator (max heap)
Queue maxHeap = new PriorityQueue<>(Collections.reverseOrder());
maxHeap.add(30);
maxHeap.add(10);
maxHeap.add(20);
System.out.println("PriorityQueue (max heap):");
while (!maxHeap.isEmpty()) {
System.out.print(maxHeap.poll() + " ");
}
System.out.println();
// Deque (Double-ended queue)
Deque deque = new ArrayDeque<>();
deque.addFirst("Front");
deque.addLast("Middle");
deque.addLast("Back");
System.out.println("\nDeque: " + deque);
System.out.println("Remove first: " + deque.removeFirst());
System.out.println("Remove last: " + deque.removeLast());
System.out.println("Deque after removal: " + deque);
}
// ========== ITERATOR DEMONSTRATION ==========
static void iteratorDemo() {
List fruits = new ArrayList<>(Arrays.asList("Apple", "Banana", "Cherry", "Date"));
// Traditional iterator
System.out.println("Using Iterator:");
Iterator iterator = fruits.iterator();
while (iterator.hasNext()) {
String fruit = iterator.next();
if (fruit.equals("Banana")) {
iterator.remove(); // Safe removal
}
System.out.println(fruit);
}
System.out.println("After removal: " + fruits);
// ListIterator (bidirectional)
List colors = new ArrayList<>(Arrays.asList("Red", "Green", "Blue"));
ListIterator listIterator = colors.listIterator();
System.out.println("\nUsing ListIterator (forward):");
while (listIterator.hasNext()) {
System.out.println(listIterator.next());
}
System.out.println("Using ListIterator (backward):");
while (listIterator.hasPrevious()) {
System.out.println(listIterator.previous());
}
// Enhanced for loop (internally uses iterator)
System.out.println("\nEnhanced for loop:");
for (String color : colors) {
System.out.println(color);
}
// Java 8+ forEach
System.out.println("\nJava 8 forEach:");
colors.forEach(color -> System.out.println(color));
}
// ========== COLLECTIONS UTILITY CLASS ==========
static void collectionsUtilityDemo() {
List numbers = new ArrayList<>(Arrays.asList(5, 2, 8, 1, 9, 3, 7, 4, 6));
System.out.println("Original list: " + numbers);
// Sorting
Collections.sort(numbers);
System.out.println("Sorted: " + numbers);
// Reverse
Collections.reverse(numbers);
System.out.println("Reversed: " + numbers);
// Shuffle
Collections.shuffle(numbers);
System.out.println("Shuffled: " + numbers);
// Binary search (list must be sorted)
Collections.sort(numbers);
int index = Collections.binarySearch(numbers, 7);
System.out.println("Binary search for 7: index " + index);
// Min and max
System.out.println("Min: " + Collections.min(numbers));
System.out.println("Max: " + Collections.max(numbers));
// Fill
List list = new ArrayList<>(Arrays.asList("A", "B", "C", "D"));
Collections.fill(list, "X");
System.out.println("Filled list: " + list);
// Frequency
List words = Arrays.asList("apple", "banana", "apple", "cherry", "apple");
int frequency = Collections.frequency(words, "apple");
System.out.println("Frequency of 'apple': " + frequency);
// Disjoint (no common elements)
List list1 = Arrays.asList(1, 2, 3);
List list2 = Arrays.asList(4, 5, 6);
List list3 = Arrays.asList(3, 4, 5);
System.out.println("list1 and list2 disjoint? " + Collections.disjoint(list1, list2));
System.out.println("list1 and list3 disjoint? " + Collections.disjoint(list1, list3));
// Synchronized collections (thread-safe)
List syncList = Collections.synchronizedList(new ArrayList<>());
Map syncMap = Collections.synchronizedMap(new HashMap<>());
System.out.println("Created synchronized collections");
}
// ========== COMPARABLE & COMPARATOR ==========
static void comparatorDemo() {
// Comparable example (natural ordering)
List students = new ArrayList<>();
students.add(new Student("Alice", 101, 85.5));
students.add(new Student("Bob", 102, 92.0));
students.add(new Student("Charlie", 103, 78.5));
Collections.sort(students); // Uses compareTo from Student class
System.out.println("Students sorted by ID (natural order):");
students.forEach(System.out::println);
// Comparator example (custom ordering)
Comparator byName = Comparator.comparing(Student::getName);
Comparator byGrade = Comparator.comparing(Student::getGrade).reversed();
Comparator byNameThenGrade = byName.thenComparing(byGrade);
Collections.sort(students, byGrade);
System.out.println("\nStudents sorted by grade (descending):");
students.forEach(System.out::println);
Collections.sort(students, byNameThenGrade);
System.out.println("\nStudents sorted by name then grade:");
students.forEach(System.out::println);
// Comparator with lambda
Comparator byId = (s1, s2) -> Integer.compare(s1.getId(), s2.getId());
Collections.sort(students, byId);
System.out.println("\nStudents sorted by ID (using lambda):");
students.forEach(System.out::println);
}
static class Student implements Comparable {
private String name;
private int id;
private double grade;
public Student(String name, int id, double grade) {
this.name = name;
this.id = id;
this.grade = grade;
}
// Natural ordering by ID
@Override
public int compareTo(Student other) {
return Integer.compare(this.id, other.id);
}
// Getters
public String getName() { return name; }
public int getId() { return id; }
public double getGrade() { return grade; }
@Override
public String toString() {
return String.format("Student{name='%s', id=%d, grade=%.1f}", name, id, grade);
}
}
// ========== JAVA 8+ STREAMS ==========
static void streamsDemo() {
List numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
System.out.println("Original numbers: " + numbers);
// Filter and collect
List evenNumbers = numbers.stream()
.filter(n -> n % 2 == 0)
.collect(Collectors.toList());
System.out.println("Even numbers: " + evenNumbers);
// Map (transform)
List squared = numbers.stream()
.map(n -> n * n)
.collect(Collectors.toList());
System.out.println("Squared numbers: " + squared);
// Reduce
int sum = numbers.stream()
.reduce(0, Integer::sum);
System.out.println("Sum: " + sum);
// Max/Min
Optional max = numbers.stream()
.max(Integer::compare);
System.out.println("Max: " + max.orElse(0));
// Count
long count = numbers.stream()
.filter(n -> n > 5)
.count();
System.out.println("Count > 5: " + count);
// AnyMatch/AllMatch/NoneMatch
boolean anyEven = numbers.stream()
.anyMatch(n -> n % 2 == 0);
System.out.println("Any even? " + anyEven);
// Grouping
List words = Arrays.asList("apple", "banana", "cherry", "date", "elderberry");
Map> byLength = words.stream()
.collect(Collectors.groupingBy(String::length));
System.out.println("Words grouped by length: " + byLength);
// Parallel stream
List parallelProcessed = numbers.parallelStream()
.map(n -> n * 2)
.collect(Collectors.toList());
System.out.println("Parallel processed: " + parallelProcessed);
}
}
10. β‘ Advanced Java Concepts
Advanced Java concepts build upon the fundamentals to create robust, efficient, and scalable applications. These features are essential for enterprise-level development.
Advanced Topics Covered
- Multithreading & Concurrency: Parallel execution
- Java I/O & NIO: File and network operations
- Generics: Type-safe collections
- Annotations: Metadata for code
- Lambda Expressions: Functional programming
- Streams API: Functional operations on collections
- JDBC: Database connectivity
- Java Modules: Modular programming (Java 9+)
Enterprise Java Features
Modern Java development includes:
1. Spring Framework: Dependency injection, MVC
2. JPA/Hibernate: Object-relational mapping
3. Microservices: Spring Boot, REST APIs
4. Testing: JUnit, Mockito
5. Build Tools: Maven, Gradle
Example: Advanced Java Concepts
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.*;
import java.io.*;
import java.nio.file.*;
import java.sql.*;
import java.time.*;
import java.util.function.*;
public class AdvancedJavaConcepts {
public static void main(String[] args) throws Exception {
System.out.println("=== MULTITHREADING & CONCURRENCY ===");
multithreadingDemo();
System.out.println("\n=== GENERICS ===");
genericsDemo();
System.out.println("\n=== LAMBDA EXPRESSIONS ===");
lambdaDemo();
System.out.println("\n=== STREAMS API ===");
streamsApiDemo();
System.out.println("\n=== OPTIONAL CLASS ===");
optionalDemo();
System.out.println("\n=== DATE-TIME API (Java 8+) ===");
dateTimeDemo();
System.out.println("\n=== ANNOTATIONS ===");
annotationsDemo();
System.out.println("\n=== JAVA I/O & NIO ===");
ioDemo();
System.out.println("\n=== JDBC (DATABASE CONNECTIVITY) ===");
jdbcDemo();
System.out.println("\n=== JAVA MODULES (Java 9+) ===");
modulesDemo();
}
// ========== MULTITHREADING ==========
static void multithreadingDemo() throws InterruptedException, ExecutionException {
// Thread creation
Thread thread1 = new Thread(() -> {
for (int i = 1; i <= 3; i++) {
System.out.println("Thread-1: " + i);
try { Thread.sleep(500); } catch (InterruptedException e) {}
}
});
Thread thread2 = new Thread(() -> {
for (int i = 1; i <= 3; i++) {
System.out.println("Thread-2: " + i);
try { Thread.sleep(300); } catch (InterruptedException e) {}
}
});
thread1.start();
thread2.start();
thread1.join();
thread2.join();
// Thread pool with ExecutorService
ExecutorService executor = Executors.newFixedThreadPool(3);
List> futures = new ArrayList<>();
for (int i = 1; i <= 5; i++) {
final int taskId = i;
futures.add(executor.submit(() -> {
System.out.println("Task " + taskId + " executed by " + Thread.currentThread().getName());
return taskId * 10;
}));
}
// Get results
for (Future future : futures) {
System.out.println("Task result: " + future.get());
}
executor.shutdown();
// Synchronization example
Counter counter = new Counter();
Thread t1 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
counter.increment();
}
});
Thread t2 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
counter.increment();
}
});
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println("Final count (with synchronization): " + counter.getCount());
// Concurrent collections
ConcurrentHashMap concurrentMap = new ConcurrentHashMap<>();
concurrentMap.put("A", 1);
concurrentMap.put("B", 2);
concurrentMap.putIfAbsent("A", 3); // Won't replace
System.out.println("ConcurrentHashMap: " + concurrentMap);
}
static class Counter {
private int count = 0;
public synchronized void increment() {
count++;
}
public int getCount() {
return count;
}
}
// ========== GENERICS ==========
static void genericsDemo() {
// Generic class
Box intBox = new Box<>(42);
Box stringBox = new Box<>("Hello Generics");
System.out.println("Integer Box: " + intBox.get());
System.out.println("String Box: " + stringBox.get());
// Generic method
Integer[] intArray = {1, 2, 3, 4, 5};
String[] strArray = {"A", "B", "C", "D"};
System.out.println("Integer array contains 3: " + contains(intArray, 3));
System.out.println("String array contains 'X': " + contains(strArray, "X"));
// Bounded type parameters
System.out.println("Max of 5, 10: " + maximum(5, 10));
System.out.println("Max of 3.14, 2.71: " + maximum(3.14, 2.71));
// Wildcards
List intList = Arrays.asList(1, 2, 3);
List doubleList = Arrays.asList(1.1, 2.2, 3.3);
List numberList = Arrays.asList(1, 2.5, 3);
System.out.println("Sum of integers: " + sumOfList(intList));
System.out.println("Sum of doubles: " + sumOfList(doubleList));
System.out.println("Sum of numbers: " + sumOfList(numberList));
// Generic class with multiple type parameters
Pair pair = new Pair<>("Age", 25);
System.out.println("Pair: " + pair.getKey() + " = " + pair.getValue());
}
// Generic class
static class Box {
private T value;
public Box(T value) {
this.value = value;
}
public T get() {
return value;
}
public void set(T value) {
this.value = value;
}
}
// Generic method
static boolean contains(T[] array, T element) {
for (T item : array) {
if (item.equals(element)) {
return true;
}
}
return false;
}
// Bounded type parameter
static > T maximum(T a, T b) {
return a.compareTo(b) > 0 ? a : b;
}
// Wildcard method
static double sumOfList(List<? extends Number> list) {
double sum = 0.0;
for (Number num : list) {
sum += num.doubleValue();
}
return sum;
}
// Multiple type parameters
static class Pair {
private K key;
private V value;
public Pair(K key, V value) {
this.key = key;
this.value = value;
}
public K getKey() { return key; }
public V getValue() { return value; }
}
// ========== LAMBDA EXPRESSIONS ==========
static void lambdaDemo() {
// Traditional way (anonymous class)
Runnable oldWay = new Runnable() {
@Override
public void run() {
System.out.println("Running old way");
}
};
// Lambda way
Runnable newWay = () -> System.out.println("Running new way");
oldWay.run();
newWay.run();
// Functional interfaces with lambdas
Calculator add = (a, b) -> a + b;
Calculator multiply = (a, b) -> a * b;
System.out.println("5 + 3 = " + add.calculate(5, 3));
System.out.println("5 * 3 = " + multiply.calculate(5, 3));
// Method references
List names = Arrays.asList("Alice", "Bob", "Charlie");
names.forEach(System.out::println);
// Comparator with lambda
List people = Arrays.asList(
new Person("Alice", 25),
new Person("Bob", 30),
new Person("Charlie", 20)
);
// Sort by age
people.sort((p1, p2) -> Integer.compare(p1.getAge(), p2.getAge()));
System.out.println("Sorted by age: " + people);
// Sort by name
people.sort(Comparator.comparing(Person::getName));
System.out.println("Sorted by name: " + people);
// Predicate (returns boolean)
Predicate isEven = n -> n % 2 == 0;
System.out.println("Is 4 even? " + isEven.test(4));
// Function (transforms input)
Function stringLength = String::length;
System.out.println("Length of 'Hello': " + stringLength.apply("Hello"));
// Consumer (accepts input, returns void)
Consumer printer = System.out::println;
printer.accept("Hello Consumer!");
// Supplier (provides values)
Supplier randomSupplier = Math::random;
System.out.println("Random number: " + randomSupplier.get());
}
// Functional interface
@FunctionalInterface
interface Calculator {
int calculate(int a, int b);
}
static class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() { return name; }
public int getAge() { return age; }
@Override
public String toString() {
return name + "(" + age + ")";
}
}
// ========== STREAMS API ==========
static void streamsApiDemo() {
List numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// Intermediate operations (lazy)
Stream stream = numbers.stream()
.filter(n -> n % 2 == 0) // Even numbers
.map(n -> n * 2) // Double them
.sorted(Comparator.reverseOrder()); // Sort descending
// Terminal operation (eager)
List result = stream.collect(Collectors.toList());
System.out.println("Processed numbers: " + result);
// More stream operations
long count = numbers.stream().count();
System.out.println("Count: " + count);
int sum = numbers.stream()
.mapToInt(Integer::intValue)
.sum();
System.out.println("Sum: " + sum);
Optional max = numbers.stream().max(Integer::compare);
max.ifPresent(m -> System.out.println("Max: " + m));
// Grouping
List words = Arrays.asList("apple", "banana", "cherry", "date", "elderberry");
Map> byLength = words.stream()
.collect(Collectors.groupingBy(String::length));
System.out.println("Words by length: " + byLength);
// Partitioning
Map> partitioned = numbers.stream()
.collect(Collectors.partitioningBy(n -> n > 5));
System.out.println("Numbers > 5: " + partitioned.get(true));
System.out.println("Numbers <= 5: " + partitioned.get(false));
// Reduce
Optional product = numbers.stream()
.reduce((a, b) -> a * b);
System.out.println("Product: " + product.orElse(0));
// Parallel stream
long parallelCount = numbers.parallelStream()
.filter(n -> n % 2 == 0)
.count();
System.out.println("Even numbers (parallel): " + parallelCount);
}
// ========== OPTIONAL CLASS ==========
static void optionalDemo() {
// Creating Optionals
Optional empty = Optional.empty();
Optional present = Optional.of("Hello");
Optional nullable = Optional.ofNullable(null);
System.out.println("Empty optional: " + empty);
System.out.println("Present optional: " + present);
System.out.println("Nullable optional: " + nullable);
// Checking and getting
if (present.isPresent()) {
System.out.println("Value: " + present.get());
}
// Default values
String value1 = empty.orElse("Default");
String value2 = present.orElse("Default");
System.out.println("Empty orElse: " + value1);
System.out.println("Present orElse: " + value2);
// orElseGet with Supplier
String value3 = empty.orElseGet(() -> "Generated default");
System.out.println("orElseGet: " + value3);
// orElseThrow
try {
String value4 = empty.orElseThrow(() -> new IllegalArgumentException("No value"));
} catch (IllegalArgumentException e) {
System.out.println("orElseThrow caught: " + e.getMessage());
}
// ifPresent
present.ifPresent(val -> System.out.println("Value exists: " + val));
// map and filter
Optional upper = present.map(String::toUpperCase);
System.out.println("Mapped to uppercase: " + upper.orElse("none"));
Optional filtered = present.filter(val -> val.length() > 10);
System.out.println("Filtered (length > 10): " + filtered.orElse("none"));
// flatMap
Optional> nested = Optional.of(Optional.of("Nested"));
Optional flattened = nested.flatMap(Function.identity());
System.out.println("Flattened: " + flattened.orElse("none"));
}
// ========== DATE-TIME API ==========
static void dateTimeDemo() {
// Current dates/times
LocalDate today = LocalDate.now();
LocalTime now = LocalTime.now();
LocalDateTime current = LocalDateTime.now();
System.out.println("Today: " + today);
System.out.println("Now: " + now);
System.out.println("Current: " + current);
// Creating specific dates
LocalDate birthday = LocalDate.of(1990, Month.JANUARY, 15);
LocalTime meetingTime = LocalTime.of(14, 30);
LocalDateTime event = LocalDateTime.of(2024, 12, 25, 18, 0);
System.out.println("Birthday: " + birthday);
System.out.println("Meeting: " + meetingTime);
System.out.println("Event: " + event);
// Manipulating dates
LocalDate nextWeek = today.plusWeeks(1);
LocalDate lastMonth = today.minusMonths(1);
LocalDate nextYear = today.plusYears(1);
System.out.println("Next week: " + nextWeek);
System.out.println("Last month: " + lastMonth);
System.out.println("Next year: " + nextYear);
// Comparing dates
boolean isBefore = birthday.isBefore(today);
boolean isAfter = nextWeek.isAfter(today);
System.out.println("Birthday is before today? " + isBefore);
System.out.println("Next week is after today? " + isAfter);
// Period and Duration
Period age = Period.between(birthday, today);
System.out.println("Age: " + age.getYears() + " years, " +
age.getMonths() + " months, " +
age.getDays() + " days");
// Formatting
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm");
String formatted = current.format(formatter);
System.out.println("Formatted: " + formatted);
// Parsing
LocalDateTime parsed = LocalDateTime.parse("25/12/2024 18:00", formatter);
System.out.println("Parsed: " + parsed);
// Time zones
ZonedDateTime zoned = ZonedDateTime.now(ZoneId.of("America/New_York"));
System.out.println("New York time: " + zoned);
// Instant (machine time)
Instant instant = Instant.now();
System.out.println("Instant: " + instant);
}
// ========== ANNOTATIONS ==========
static void annotationsDemo() {
// Using annotations
MyClass obj = new MyClass();
obj.deprecatedMethod();
obj.newMethod();
// Reflection to read annotations
Class<?> clazz = MyClass.class;
if (clazz.isAnnotationPresent(Author.class)) {
Author author = clazz.getAnnotation(Author.class);
System.out.println("Class author: " + author.name() + ", version: " + author.version());
}
// Method annotations
try {
Method method = clazz.getMethod("deprecatedMethod");
if (method.isAnnotationPresent(Deprecated.class)) {
System.out.println("deprecatedMethod is marked as @Deprecated");
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
// Custom annotation
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@interface Author {
String name();
String version() default "1.0";
}
@Author(name = "John Doe", version = "2.0")
static class MyClass {
@Deprecated
public void deprecatedMethod() {
System.out.println("This method is deprecated");
}
@SuppressWarnings("unused")
public void newMethod() {
System.out.println("This is the new method");
}
}
// ========== I/O DEMO ==========
static void ioDemo() throws IOException {
// Traditional I/O
try (BufferedReader reader = new BufferedReader(new FileReader("test.txt"));
BufferedWriter writer = new BufferedWriter(new FileWriter("output.txt"))) {
String line;
while ((line = reader.readLine()) != null) {
writer.write(line.toUpperCase());
writer.newLine();
}
System.out.println("File processed with traditional I/O");
} catch (FileNotFoundException e) {
System.out.println("File not found, creating sample...");
// Create sample file
try (BufferedWriter writer = new BufferedWriter(new FileWriter("test.txt"))) {
writer.write("Line 1: Hello World");
writer.newLine();
writer.write("Line 2: Java I/O Demo");
writer.newLine();
writer.write("Line 3: File Operations");
}
}
// NIO (New I/O)
Path source = Paths.get("test.txt");
Path destination = Paths.get("copy.txt");
Files.copy(source, destination, StandardCopyOption.REPLACE_EXISTING);
System.out.println("File copied using NIO");
// Read all lines
List lines = Files.readAllLines(source);
System.out.println("File contents (" + lines.size() + " lines):");
lines.forEach(System.out::println);
// File attributes
System.out.println("File size: " + Files.size(source) + " bytes");
System.out.println("Is regular file? " + Files.isRegularFile(source));
System.out.println("Is readable? " + Files.isReadable(source));
// Delete created files
Files.deleteIfExists(destination);
Files.deleteIfExists(Paths.get("output.txt"));
}
// ========== JDBC DEMO ==========
static void jdbcDemo() {
// Note: This is a demonstration. Actual database needed for real execution.
System.out.println("JDBC Demonstration (conceptual):");
// Connection URL pattern
String url = "jdbc:mysql://localhost:3306/mydatabase";
String username = "root";
String password = "password";
try (Connection connection = DriverManager.getConnection(url, username, password)) {
System.out.println("Database connected!");
// Create statement
Statement statement = connection.createStatement();
// Create table
String createTableSQL = """
CREATE TABLE IF NOT EXISTS students (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100) NOT NULL,
age INT,
grade DOUBLE
)
""";
statement.execute(createTableSQL);
// Insert data
String insertSQL = """
INSERT INTO students (name, age, grade)
VALUES ('Alice', 20, 85.5), ('Bob', 21, 92.0)
""";
int rowsInserted = statement.executeUpdate(insertSQL);
System.out.println(rowsInserted + " rows inserted");
// Query data
String selectSQL = "SELECT * FROM students";
ResultSet resultSet = statement.executeQuery(selectSQL);
while (resultSet.next()) {
int id = resultSet.getInt("id");
String name = resultSet.getString("name");
int age = resultSet.getInt("age");
double grade = resultSet.getDouble("grade");
System.out.printf("Student: id=%d, name=%s, age=%d, grade=%.1f%n",
id, name, age, grade);
}
// Prepared statement (prevents SQL injection)
String preparedSQL = "INSERT INTO students (name, age, grade) VALUES (?, ?, ?)";
try (PreparedStatement pstmt = connection.prepareStatement(preparedSQL)) {
pstmt.setString(1, "Charlie");
pstmt.setInt(2, 22);
pstmt.setDouble(3, 78.5);
pstmt.executeUpdate();
}
// Transactions
connection.setAutoCommit(false);
try {
// Multiple operations
statement.executeUpdate("UPDATE students SET grade = grade + 5 WHERE age > 20");
statement.executeUpdate("DELETE FROM students WHERE grade < 60");
connection.commit();
System.out.println("Transaction committed");
} catch (SQLException e) {
connection.rollback();
System.out.println("Transaction rolled back");
}
} catch (SQLException e) {
System.out.println("Database error: " + e.getMessage());
}
}
// ========== MODULES DEMO ==========
static void modulesDemo() {
System.out.println("Java Modules (Project Jigsaw) - Java 9+");
System.out.println("""
Module System Benefits:
1. Strong encapsulation
2. Reliable configuration
3. Scalable development
4. Improved performance
Module Declaration (module-info.java):
module com.example.myapp {
requires java.base; // Implicit
requires java.sql;
requires transitive com.example.utils;
exports com.example.myapp.api;
exports com.example.myapp.internal to com.example.test;
opens com.example.myapp.model to com.example.persistence;
uses com.example.spi.ServiceProvider;
provides com.example.spi.Service with com.example.myapp.ServiceImpl;
}
Key Concepts:
- Module: Group of packages with module-info.java
- Requires: Dependencies on other modules
- Exports: Packages accessible to other modules
- Opens: Packages accessible via reflection
- Provides/Uses: Service loader mechanism
""");
}
}
Codcups
Master Java - Complete Programming Course