Welcome to Java
Java is a powerful, object-oriented programming language known for its "write once, run anywhere" capability. Developed by Sun Microsystems in 1995, Java is designed to be platform-independent through the Java Virtual Machine (JVM). It's widely used for building enterprise-scale applications, Android apps, web services, and large systems. Java's strong typing, automatic memory management (garbage collection), and extensive standard library make it a robust choice for mission-critical applications across industries.
Introduction to Java
How to install Java and write your first "Hello, World!" program.
Step 1: Download and Install Java
-
Visit the Official Website
Go to Oracle Java Downloads or OpenJDK and download the latest LTS version of Java for your operating system. -
Run the Installer
- For Windows: Run the downloaded .exe file and follow the installation wizard.
- For Mac: Use the .dmg installer or install via Homebrew with
brew install openjdk - For Linux: Use your package manager (e.g., for Ubuntu:
sudo apt install openjdk-17-jdk)
-
Verify the Installation
Open a terminal or command prompt and type:shjava -versionThis should display the installed Java version.
Step 2: Choose an IDE or Code Editor
While you can write Java in any text editor, IDEs provide powerful features:
- IntelliJ IDEA β Most popular Java IDE with excellent features
- Eclipse β Free, open-source IDE with strong community
- VS Code β Lightweight with Java extensions
- NetBeans β Another free, full-featured IDE
Step 3: Write and Run Your First Java Program
-
Create a Java File
Create a file namedHelloWorld.javawith the following content:javapublic class HelloWorld { public static void main(String[] args) { System.out.println("Hello, World!"); } } -
Compile the Program
Open terminal/command prompt, navigate to the file location, and run:shjavac HelloWorld.java -
Run the Program
Execute the compiled class file:shjava HelloWorldYou should see the output:
Hello, World!
Congratulations! You have successfully installed Java and run your first program. π
Java Syntax Basics
1. Class Structure
Every Java program must have at least one class, and the filename must match the class name.
javapublic class MyClass {
// Class content goes here
}
2. Main Method
The main method is the entry point of any Java application.
javapublic static void main(String[] args) {
// Program execution starts here
}
3. Semicolons and Braces
Java requires semicolons at the end of statements and uses curly braces {} to define code blocks.
javaif (condition) {
// Code block
statement;
}
4. Case Sensitivity
Java is case-sensitive. MyVariable and myvariable are different identifiers.
javaint count = 5;
int Count = 10; // Different variable
5. Comments
Java supports single-line and multi-line comments.
java// This is a single-line comment
/*
This is a multi-line comment
that spans multiple lines
*/
/**
* This is a Javadoc comment used for documentation
*/
Conclusion
Understanding Java's basic syntax is essential for writing correct programs. Key points include proper class structure, the main method requirement, and consistent use of semicolons and braces.
System.out.println
The System.out.println() method in Java is used to display output to the console. It's one of the most commonly used methods for debugging and user interaction.
1. Basic Usage
Print a string or variable value:
javaSystem.out.println("Hello, World!"); // Outputs: Hello, World!
System.out.println(42); // Outputs: 42
2. Printing Multiple Values
Use string concatenation with the + operator:
javaString name = "Alice";
int age = 25;
System.out.println("Name: " + name + ", Age: " + age);
// Outputs: Name: Alice, Age: 25
3. System.out.print() vs System.out.println()
println() adds a newline at the end, while print() does not:
javaSystem.out.print("Hello "); // No newline
System.out.print("World"); // Continues on same line
System.out.println(); // Adds newline
// Outputs: Hello World
4. Formatting Output
Use System.out.printf() for formatted output:
javadouble price = 19.99;
System.out.printf("Price: $%.2f", price);
// Outputs: Price: $19.99
Conclusion
Java provides multiple ways to output data to the console. System.out.println() is the most common for simple output, while printf() offers formatting capabilities.
Arithmetic Operators
Java provides arithmetic operators for basic mathematical operations.
Basic Arithmetic Operators
javaint a = 15;
int b = 4;
System.out.println(a + b); // 19 (addition)
System.out.println(a - b); // 11 (subtraction)
System.out.println(a * b); // 60 (multiplication)
System.out.println(a / b); // 3 (integer division)
System.out.println(a % b); // 3 (modulus)
double x = 15.0;
double y = 4.0;
System.out.println(x / y); // 3.75 (floating-point division)
Increment and Decrement
javaint count = 5;
count++; // post-increment: count becomes 6
++count; // pre-increment: count becomes 7
count--; // post-decrement: count becomes 6
--count; // pre-decrement: count becomes 5
Comparison Operators
Comparison operators compare values and return boolean results.
javaint x = 7;
int y = 10;
System.out.println(x == y); // false (equal to)
System.out.println(x != y); // true (not equal to)
System.out.println(x > y); // false
System.out.println(x < y); // true
System.out.println(x >= 7); // true
System.out.println(y <= 7); // false
Object Comparison
javaString s1 = "hello";
String s2 = "hello";
String s3 = new String("hello");
System.out.println(s1 == s2); // true (string pool)
System.out.println(s1 == s3); // false (different objects)
System.out.println(s1.equals(s3)); // true (content comparison)
Logical Operators
Logical operators combine boolean expressions.
javaboolean isSunny = true;
boolean isWarm = false;
System.out.println(isSunny && isWarm); // false (AND)
System.out.println(isSunny || isWarm); // true (OR)
System.out.println(!isWarm); // true (NOT)
Short-Circuit Evaluation
java// && and || are short-circuit operators
int value = 10;
if (value != 0 && 100 / value > 5) {
// Safe from division by zero
System.out.println("Condition met");
}
Bitwise Operators
Bitwise operators work on individual bits of integer types.
javaint a = 6; // binary: 110
int b = 3; // binary: 011
System.out.println(a & b); // 2 (binary 010) - AND
System.out.println(a | b); // 7 (binary 111) - OR
System.out.println(a ^ b); // 5 (binary 101) - XOR
System.out.println(~a); // -7 (complement)
System.out.println(a << 1); // 12 (binary 1100) - left shift
System.out.println(a >> 1); // 3 (binary 011) - right shift
System.out.println(a >>> 1); // 3 (unsigned right shift)
Assignment Operators
Assignment operators assign values to variables, often with operations.
javaint x = 10; // simple assignment
x += 5; // equivalent to x = x + 5 β 15
x -= 3; // equivalent to x = x - 3 β 12
x *= 2; // equivalent to x = x * 2 β 24
x /= 4; // equivalent to x = x / 4 β 6
x %= 4; // equivalent to x = x % 4 β 2
// Also works with other operators
x &= 3; // bitwise AND assignment
x |= 8; // bitwise OR assignment
x <<= 1; // left shift assignment
Primitive Data Types
Java has 8 primitive data types that store simple values directly in memory.
1. Integer Types
javabyte smallNumber = 100; // 8-bit, range: -128 to 127
short mediumNumber = 10000; // 16-bit, range: -32,768 to 32,767
int number = 100000; // 32-bit, most commonly used
long bigNumber = 1000000000L; // 64-bit, note the 'L' suffix
2. Floating-Point Types
javafloat price = 19.99f; // 32-bit, note the 'f' suffix
double precisePrice = 19.999; // 64-bit, default for decimals
3. Character and Boolean
javachar letter = 'A'; // 16-bit Unicode character
boolean isJavaFun = true; // true or false
4. Default Values
Primitives have default values when declared as instance variables:
javaint defaultInt; // 0
double defaultDouble; // 0.0
boolean defaultBool; // false
char defaultChar; // '\u0000' (null character)
Strings in Java
Strings in Java are objects that represent sequences of characters. They are immutable.
Creating Strings
java// String literals (go to string pool)
String s1 = "Hello";
String s2 = "World";
// Using constructor
String s3 = new String("Hello World");
// Concatenation
String greeting = s1 + " " + s2;
System.out.println(greeting); // Hello World
String Immutability
javaString str = "hello";
str.concat(" world"); // Returns new string, original unchanged
System.out.println(str); // Still "hello"
str = str.concat(" world"); // Reassign to see change
System.out.println(str); // "hello world"
String Methods
Java String class provides many useful methods for string manipulation.
Common String Methods
javaString text = " Hello World ";
System.out.println(text.length()); // 13
System.out.println(text.trim()); // "Hello World"
System.out.println(text.toUpperCase()); // " HELLO WORLD "
System.out.println(text.toLowerCase()); // " hello world "
System.out.println(text.charAt(1)); // 'H'
System.out.println(text.substring(1, 6)); // "Hello"
System.out.println(text.replace("World", "Java")); // " Hello Java "
Searching and Checking
javaString str = "Java Programming";
System.out.println(str.contains("Pro")); // true
System.out.println(str.startsWith("Java")); // true
System.out.println(str.endsWith("ing")); // true
System.out.println(str.indexOf("a")); // 1
System.out.println(str.lastIndexOf("a")); // 3
System.out.println(str.isEmpty()); // false
String Formatting
Java provides several ways to format strings.
String.format()
javaString name = "Alice";
int age = 25;
double salary = 50000.50;
String message = String.format("Name: %s, Age: %d, Salary: $%,.2f",
name, age, salary);
System.out.println(message);
// Output: Name: Alice, Age: 25, Salary: $50,000.50
StringBuilder for Efficient Concatenation
javaStringBuilder sb = new StringBuilder();
sb.append("Hello");
sb.append(" ");
sb.append("World");
String result = sb.toString();
System.out.println(result); // Hello World
Text Blocks (Java 15+)
javaString html = """
<html>
<body>
<h1>Hello World</h1>
</body>
</html>
""";
System.out.println(html);
Arrays in Java
Arrays in Java are fixed-size containers that store multiple values of the same type.
1. Declaring and Initializing Arrays
java// Declaration
int[] numbers;
// Initialization with size
numbers = new int[5];
// Declaration and initialization in one line
int[] scores = new int[3];
// Initialization with values
int[] primes = {2, 3, 5, 7, 11};
2. Accessing Array Elements
javaint[] numbers = {10, 20, 30, 40, 50};
System.out.println(numbers[0]); // Outputs: 10
numbers[2] = 35; // Modify third element
3. Array Length
javaint[] numbers = {1, 2, 3, 4, 5};
System.out.println(numbers.length); // Outputs: 5
4. Multi-dimensional Arrays
javaint[][] matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
System.out.println(matrix[1][2]); // Outputs: 6
Array Indexing
Arrays in Java use zero-based indexing to access elements.
Accessing Array Elements
javaint[] numbers = {10, 20, 30, 40, 50};
System.out.println(numbers[0]); // First element: 10
System.out.println(numbers[2]); // Third element: 30
System.out.println(numbers[4]); // Last element: 50
numbers[1] = 25; // Modify second element
System.out.println(numbers[1]); // Now 25
Array Index Out of Bounds
javaint[] arr = {1, 2, 3};
// This will throw ArrayIndexOutOfBoundsException
// System.out.println(arr[5]);
Multi-dimensional Array Indexing
javaint[][] matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
System.out.println(matrix[0][0]); // 1
System.out.println(matrix[1][2]); // 6
System.out.println(matrix[2][1]); // 8
Array Methods and Utilities
Java provides utility methods for working with arrays through the Arrays class.
Arrays Class Utilities
javaimport java.util.Arrays;
int[] numbers = {5, 2, 8, 1, 9};
// Sorting
Arrays.sort(numbers);
System.out.println(Arrays.toString(numbers)); // [1, 2, 5, 8, 9]
// Searching (array must be sorted)
int index = Arrays.binarySearch(numbers, 5);
System.out.println(index); // 2
// Comparing arrays
int[] arr1 = {1, 2, 3};
int[] arr2 = {1, 2, 3};
System.out.println(Arrays.equals(arr1, arr2)); // true
// Filling arrays
int[] filled = new int[5];
Arrays.fill(filled, 10);
System.out.println(Arrays.toString(filled)); // [10, 10, 10, 10, 10]
Copying Arrays
javaint[] original = {1, 2, 3, 4, 5};
// Using Arrays.copyOf
int[] copy1 = Arrays.copyOf(original, 3); // [1, 2, 3]
int[] copy2 = Arrays.copyOf(original, 7); // [1, 2, 3, 4, 5, 0, 0]
// Using System.arraycopy
int[] copy3 = new int[5];
System.arraycopy(original, 0, copy3, 0, 5);
ArrayList
ArrayList is a resizable array implementation of the List interface.
Basic ArrayList Operations
javaimport java.util.ArrayList;
ArrayList<String> list = new ArrayList<>();
// Adding elements
list.add("Apple");
list.add("Banana");
list.add("Cherry");
// Accessing elements
System.out.println(list.get(0)); // Apple
System.out.println(list.size()); // 3
// Modifying elements
list.set(1, "Blueberry");
System.out.println(list); // [Apple, Blueberry, Cherry]
// Removing elements
list.remove(0);
list.remove("Cherry");
System.out.println(list); // [Blueberry]
Iterating through ArrayList
javaArrayList<Integer> numbers = new ArrayList<>();
numbers.add(10);
numbers.add(20);
numbers.add(30);
// Enhanced for loop
for (int num : numbers) {
System.out.println(num);
}
// Traditional for loop
for (int i = 0; i < numbers.size(); i++) {
System.out.println(numbers.get(i));
}
// Using forEach (Java 8+)
numbers.forEach(System.out::println);
LinkedList
LinkedList is a doubly-linked list implementation that allows efficient insertions and deletions.
LinkedList Operations
javaimport java.util.LinkedList;
LinkedList<String> linkedList = new LinkedList<>();
// Adding elements
linkedList.add("First");
linkedList.add("Second");
linkedList.addFirst("New First"); // Add at beginning
linkedList.addLast("Last"); // Add at end
System.out.println(linkedList); // [New First, First, Second, Last]
// Accessing elements
System.out.println(linkedList.getFirst()); // New First
System.out.println(linkedList.getLast()); // Last
// Removing elements
linkedList.removeFirst();
linkedList.removeLast();
System.out.println(linkedList); // [First, Second]
LinkedList as Queue/Deque
javaLinkedList<Integer> queue = new LinkedList<>();
// Queue operations
queue.offer(10); // add to end
queue.offer(20);
queue.offer(30);
System.out.println(queue.poll()); // remove from front: 10
System.out.println(queue.peek()); // view front: 20
// Stack operations
queue.push(5); // push to front
System.out.println(queue.pop()); // pop from front: 5
HashMap
HashMap stores key-value pairs and provides constant-time performance for basic operations.
Basic HashMap Operations
javaimport java.util.HashMap;
HashMap<String, Integer> map = new HashMap<>();
// Adding key-value pairs
map.put("Alice", 25);
map.put("Bob", 30);
map.put("Charlie", 35);
// Accessing values
System.out.println(map.get("Alice")); // 25
System.out.println(map.get("David")); // null
// Checking existence
System.out.println(map.containsKey("Bob")); // true
System.out.println(map.containsValue(40)); // false
// Removing entries
map.remove("Charlie");
System.out.println(map.size()); // 2
Iterating through HashMap
javaHashMap<String, String> countries = new HashMap<>();
countries.put("US", "United States");
countries.put("UK", "United Kingdom");
countries.put("IN", "India");
// Iterate through keys
for (String code : countries.keySet()) {
System.out.println(code + ": " + countries.get(code));
}
// Iterate through entries
for (HashMap.Entry<String, String> entry : countries.entrySet()) {
System.out.println(entry.getKey() + " = " + entry.getValue());
}
// Using forEach (Java 8+)
countries.forEach((k, v) -> System.out.println(k + ": " + v));
HashSet
HashSet stores unique elements and provides constant-time performance for basic operations.
Basic HashSet Operations
javaimport java.util.HashSet;
HashSet<String> set = new HashSet<>();
// Adding elements
set.add("Apple");
set.add("Banana");
set.add("Apple"); // Duplicate - won't be added
System.out.println(set); // [Apple, Banana]
System.out.println(set.size()); // 2
// Checking existence
System.out.println(set.contains("Banana")); // true
System.out.println(set.contains("Cherry")); // false
// Removing elements
set.remove("Apple");
System.out.println(set); // [Banana]
Set Operations
javaHashSet<Integer> set1 = new HashSet<>();
set1.add(1);
set1.add(2);
set1.add(3);
HashSet<Integer> set2 = new HashSet<>();
set2.add(2);
set2.add(3);
set2.add(4);
// Union
HashSet<Integer> union = new HashSet<>(set1);
union.addAll(set2);
System.out.println("Union: " + union); // [1, 2, 3, 4]
// Intersection
HashSet<Integer> intersection = new HashSet<>(set1);
intersection.retainAll(set2);
System.out.println("Intersection: " + intersection); // [2, 3]
// Difference
HashSet<Integer> difference = new HashSet<>(set1);
difference.removeAll(set2);
System.out.println("Difference: " + difference); // [1]
Variables in Java
Variables in Java are strongly typed and must be declared before use.
Variable Declaration and Initialization
java// Primitive variables
int age = 25;
double salary = 50000.50;
char grade = 'A';
boolean isActive = true;
// Reference variables
String name = "John Doe";
int[] numbers = {1, 2, 3};
// Multiple declaration
int x = 5, y = 10, z = 15;
// Constants (final variables)
final double PI = 3.14159;
final int MAX_USERS = 100;
Variable Scope
javapublic class ScopeExample {
int instanceVar = 10; // Instance variable
public void method() {
int localVar = 20; // Local variable
System.out.println(instanceVar); // Can access instance variable
System.out.println(localVar); // Can access local variable
}
public void anotherMethod() {
// System.out.println(localVar); // Error: localVar not accessible here
System.out.println(instanceVar); // Can access instance variable
}
}
Conditional Statements: if, else, switch
Java provides if-else and switch statements for conditional execution.
if-else Statements
javaint score = 85;
if (score >= 90) {
System.out.println("Grade: A");
} else if (score >= 80) {
System.out.println("Grade: B"); // This executes
} else if (score >= 70) {
System.out.println("Grade: C");
} else {
System.out.println("Grade: F");
}
Ternary Operator
javaint age = 20;
String status = (age >= 18) ? "Adult" : "Minor";
System.out.println(status); // Adult
Switch Statement
javaint day = 3;
String dayName;
switch (day) {
case 1:
dayName = "Monday";
break;
case 2:
dayName = "Tuesday";
break;
case 3:
dayName = "Wednesday"; // This executes
break;
default:
dayName = "Invalid day";
}
System.out.println(dayName); // Wednesday
Switch Expressions (Java 14+)
javaint day = 3;
String dayName = switch (day) {
case 1 -> "Monday";
case 2 -> "Tuesday";
case 3 -> "Wednesday";
default -> "Invalid day";
};
System.out.println(dayName); // Wednesday
For Loops in Java
For loops in Java repeat a block of code a specific number of times.
1. Basic For Loop
javafor (int i = 0; i < 5; i++) {
System.out.println("Count: " + i);
}
// Outputs: Count: 0, Count: 1, ..., Count: 4
2. Enhanced For Loop (For-Each)
javaint[] numbers = {1, 2, 3, 4, 5};
for (int number : numbers) {
System.out.println(number);
}
// Outputs each number in the array
3. Nested For Loops
javafor (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 2; j++) {
System.out.println("i=" + i + ", j=" + j);
}
}
4. Loop Control with break and continue
javafor (int i = 0; i < 10; i++) {
if (i == 3) {
continue; // Skip iteration when i is 3
}
if (i == 7) {
break; // Exit loop when i is 7
}
System.out.println(i);
}
// Outputs: 0, 1, 2, 4, 5, 6
While Loops
While loops execute a block of code as long as a condition is true.
Basic While Loop
javaint count = 1;
while (count <= 5) {
System.out.println("Count: " + count);
count++;
}
// Output: Count: 1, Count: 2, ..., Count: 5
Do-While Loop
javaint number;
do {
System.out.println("Enter a positive number: ");
// Simulating user input
number = -1; // This would typically come from Scanner
} while (number <= 0);
// Do-while guarantees at least one execution
Infinite Loop with Break
javaint value = 0;
while (true) {
System.out.println("Value: " + value);
value++;
if (value >= 5) {
break; // Exit the loop
}
}
Do-While Loop
The do-while loop executes the code block first, then checks the condition.
Basic Do-While
javaint i = 1;
do {
System.out.println("Number: " + i);
i++;
} while (i <= 3);
// Output: Number: 1, Number: 2, Number: 3
Do-While vs While
java// While loop - may not execute if condition is false initially
int x = 10;
while (x < 5) {
System.out.println("This won't execute");
}
// Do-while loop - executes at least once
int y = 10;
do {
System.out.println("This will execute once");
} while (y < 5);
Practical Example
javaimport java.util.Scanner;
Scanner scanner = new Scanner(System.in);
int number;
do {
System.out.print("Enter a number between 1 and 10: ");
number = scanner.nextInt();
} while (number < 1 || number > 10);
System.out.println("Thank you! You entered: " + number);
Enhanced For Loop
The enhanced for loop (for-each loop) simplifies iterating over arrays and collections.
Iterating over Arrays
javaint[] numbers = {1, 2, 3, 4, 5};
// Enhanced for loop
for (int num : numbers) {
System.out.println(num);
}
// Output: 1, 2, 3, 4, 5
Iterating over Collections
javaimport java.util.ArrayList;
ArrayList<String> fruits = new ArrayList<>();
fruits.add("Apple");
fruits.add("Banana");
fruits.add("Cherry");
for (String fruit : fruits) {
System.out.println(fruit);
}
// Output: Apple, Banana, Cherry
Limitations
javaint[] numbers = {10, 20, 30, 40, 50};
// Enhanced for loop - read-only access
for (int num : numbers) {
num = num * 2; // This doesn't modify the array
System.out.println(num);
}
System.out.println(numbers[0]); // Still 10
// Traditional for loop for modification
for (int i = 0; i < numbers.length; i++) {
numbers[i] = numbers[i] * 2; // Actually modifies the array
}
System.out.println(numbers[0]); // Now 20
Loop Control Statements
Java provides break, continue, and labels for loop control.
Break Statement
javafor (int i = 1; i <= 10; i++) {
if (i == 5) {
break; // Exit loop when i is 5
}
System.out.println(i);
}
// Output: 1, 2, 3, 4
Continue Statement
javafor (int i = 1; i <= 5; i++) {
if (i == 3) {
continue; // Skip iteration when i is 3
}
System.out.println(i);
}
// Output: 1, 2, 4, 5
Labeled Break and Continue
javaouterLoop:
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 3; j++) {
if (i == 2 && j == 2) {
break outerLoop; // Break out of both loops
}
System.out.println("i=" + i + ", j=" + j);
}
}
// Output: i=1,j=1, i=1,j=2, i=1,j=3, i=2,j=1
Nested Loops
Nested loops are loops within loops, useful for multi-dimensional data.
Basic Nested Loops
java// Multiplication table
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 3; j++) {
System.out.print(i * j + "\t");
}
System.out.println(); // New line after each row
}
// Output:
// 1 2 3
// 2 4 6
// 3 6 9
Pattern Printing
java// Right triangle pattern
for (int i = 1; i <= 5; i++) {
for (int j = 1; j <= i; j++) {
System.out.print("* ");
}
System.out.println();
}
// Output:
// *
// * *
// * * *
// * * * *
// * * * * *
Nested Enhanced For Loops
javaint[][] matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
for (int[] row : matrix) {
for (int value : row) {
System.out.print(value + " ");
}
System.out.println();
}
// Output:
// 1 2 3
// 4 5 6
// 7 8 9
Defining Methods
Methods in Java define reusable blocks of code with specific functionality.
Method Syntax
java// Method definition
public static int add(int a, int b) {
return a + b;
}
// Method usage
int result = add(5, 3);
System.out.println(result); // 8
Method Parameters and Return Types
java// Void method (no return)
public static void greet(String name) {
System.out.println("Hello, " + name + "!");
}
// Method with return value
public static double calculateArea(double radius) {
return Math.PI * radius * radius;
}
// Method with multiple parameters
public static String createEmail(String firstName, String lastName, String domain) {
return firstName.toLowerCase() + "." + lastName.toLowerCase() + "@" + domain;
}
// Usage
greet("Alice"); // Hello, Alice!
double area = calculateArea(5.0);
String email = createEmail("John", "Doe", "company.com");
Method Overloading
javapublic class Calculator {
// Same method name, different parameters
public static int add(int a, int b) {
return a + b;
}
public static double add(double a, double b) {
return a + b;
}
public static int add(int a, int b, int c) {
return a + b + c;
}
}
// Usage - Java selects appropriate method based on parameters
System.out.println(Calculator.add(2, 3)); // 5 (uses first method)
System.out.println(Calculator.add(2.5, 3.5)); // 6.0 (uses second method)
System.out.println(Calculator.add(1, 2, 3)); // 6 (uses third method)
Classes and Objects
Java is an object-oriented language where classes define blueprints for objects.
1. Defining a Class
javapublic class Car {
// Fields (attributes)
String brand;
String color;
int year;
// Constructor
public Car(String brand, String color, int year) {
this.brand = brand;
this.color = color;
this.year = year;
}
// Method
public void displayInfo() {
System.out.println(brand + " " + color + " " + year);
}
}
2. Creating Objects
java// Create Car objects
Car car1 = new Car("Toyota", "Red", 2020);
Car car2 = new Car("Honda", "Blue", 2022);
// Use object methods
car1.displayInfo(); // Outputs: Toyota Red 2020
car2.displayInfo(); // Outputs: Honda Blue 2022
3. Getters and Setters
javapublic class Person {
private String name;
private int age;
// Getter
public String getName() {
return name;
}
// Setter
public void setName(String name) {
this.name = name;
}
// Similarly for age
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
Importing Packages
Java packages organize classes, and imports make them accessible.
Basic Import Syntax
java// Import single class
import java.util.ArrayList;
import java.util.Scanner;
// Import entire package
import java.util.*;
import java.io.*;
// Static import (for static members)
import static java.lang.Math.PI;
import static java.lang.Math.sqrt;
Commonly Used Packages
javaimport java.util.*; // Collections, Scanner, Date
import java.io.*; // File I/O
import java.net.*; // Networking
import java.sql.*; // Database
import java.time.*; // Date and Time API
import java.util.regex.*; // Regular Expressions
import java.util.stream.*; // Stream API
Custom Packages
java// File: com/example/utils/StringUtils.java
package com.example.utils;
public class StringUtils {
public static boolean isEmpty(String str) {
return str == null || str.trim().isEmpty();
}
public static String reverse(String str) {
return new StringBuilder(str).reverse().toString();
}
}
// Usage in another file
import com.example.utils.StringUtils;
public class Main {
public static void main(String[] args) {
System.out.println(StringUtils.isEmpty("")); // true
System.out.println(StringUtils.reverse("hello")); // olleh
}
}
File I/O
Java provides comprehensive file input/output operations.
Reading Files
javaimport java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
// Using BufferedReader
try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
// Using Scanner
import java.util.Scanner;
import java.io.File;
try (Scanner scanner = new Scanner(new File("file.txt"))) {
while (scanner.hasNextLine()) {
System.out.println(scanner.nextLine());
}
} catch (IOException e) {
e.printStackTrace();
}
Writing Files
javaimport java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
// Using BufferedWriter
try (BufferedWriter bw = new BufferedWriter(new FileWriter("output.txt"))) {
bw.write("Hello, World!");
bw.newLine();
bw.write("This is a new line");
} catch (IOException e) {
e.printStackTrace();
}
// Using PrintWriter
import java.io.PrintWriter;
try (PrintWriter pw = new PrintWriter(new FileWriter("data.txt"))) {
pw.println("Name: John Doe");
pw.println("Age: 30");
pw.printf("Salary: $%,.2f", 50000.50);
} catch (IOException e) {
e.printStackTrace();
}
File Operations
javaimport java.io.File;
File file = new File("example.txt");
System.out.println("Exists: " + file.exists());
System.out.println("Is file: " + file.isFile());
System.out.println("Is directory: " + file.isDirectory());
System.out.println("Size: " + file.length() + " bytes");
System.out.println("Path: " + file.getAbsolutePath());
// Create directory
File dir = new File("myFolder");
dir.mkdir();
// List files in directory
File folder = new File(".");
String[] files = folder.list();
for (String f : files) {
System.out.println(f);
}
Inheritance
Inheritance allows a class to inherit fields and methods from another class.
Basic Inheritance
java// Parent class
class Animal {
String name;
public Animal(String name) {
this.name = name;
}
public void eat() {
System.out.println(name + " is eating.");
}
public void sleep() {
System.out.println(name + " is sleeping.");
}
}
// Child class inheriting from Animal
class Dog extends Animal {
String breed;
public Dog(String name, String breed) {
super(name); // Call parent constructor
this.breed = breed;
}
public void bark() {
System.out.println(name + " is barking.");
}
// Overriding parent method
@Override
public void eat() {
System.out.println(name + " the " + breed + " is eating dog food.");
}
}
// Usage
Dog dog = new Dog("Buddy", "Golden Retriever");
dog.eat(); // Overridden method
dog.sleep(); // Inherited method
dog.bark(); // Dog-specific method
Method Overriding
javaclass BankAccount {
protected double balance;
public BankAccount(double initialBalance) {
this.balance = initialBalance;
}
public void withdraw(double amount) {
if (amount <= balance) {
balance -= amount;
System.out.println("Withdrew: " + amount);
} else {
System.out.println("Insufficient funds");
}
}
}
class SavingsAccount extends BankAccount {
private double interestRate;
public SavingsAccount(double initialBalance, double interestRate) {
super(initialBalance);
this.interestRate = interestRate;
}
@Override
public void withdraw(double amount) {
if (amount <= balance - 100) { // Maintain minimum balance
balance -= amount;
System.out.println("Withdrew: " + amount);
} else {
System.out.println("Cannot withdraw - minimum balance requirement");
}
}
public void applyInterest() {
balance += balance * interestRate;
System.out.println("Interest applied. New balance: " + balance);
}
}
Polymorphism
Polymorphism allows objects of different classes to be treated as objects of a common superclass.
Runtime Polymorphism
javaclass Shape {
public void draw() {
System.out.println("Drawing a shape");
}
public double area() {
return 0;
}
}
class Circle extends Shape {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
public void draw() {
System.out.println("Drawing a circle with radius " + radius);
}
@Override
public double area() {
return Math.PI * radius * radius;
}
}
class Rectangle extends Shape {
private double width, height;
public Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
@Override
public void draw() {
System.out.println("Drawing a rectangle " + width + "x" + height);
}
@Override
public double area() {
return width * height;
}
}
// Polymorphic behavior
Shape[] shapes = new Shape[3];
shapes[0] = new Shape();
shapes[1] = new Circle(5);
shapes[2] = new Rectangle(4, 6);
for (Shape shape : shapes) {
shape.draw(); // Calls appropriate version based on actual type
System.out.println("Area: " + shape.area());
}
Interface Polymorphism
javainterface Payment {
void processPayment(double amount);
boolean isSuccessful();
}
class CreditCardPayment implements Payment {
private boolean success;
@Override
public void processPayment(double amount) {
System.out.println("Processing credit card payment: {{content}}quot; + amount);
success = true;
}
@Override
public boolean isSuccessful() {
return success;
}
}
class PayPalPayment implements Payment {
private boolean success;
@Override
public void processPayment(double amount) {
System.out.println("Processing PayPal payment: {{content}}quot; + amount);
success = true;
}
@Override
public boolean isSuccessful() {
return success;
}
}
// Using interface polymorphism
Payment payment1 = new CreditCardPayment();
Payment payment2 = new PayPalPayment();
payment1.processPayment(100.0);
payment2.processPayment(50.0);
Encapsulation
Encapsulation bundles data and methods together and restricts direct access to internal state.
Basic Encapsulation
javapublic class BankAccount {
// Private fields - hidden from outside
private String accountNumber;
private double balance;
private String ownerName;
// Public constructor
public BankAccount(String accountNumber, String ownerName, double initialBalance) {
this.accountNumber = accountNumber;
this.ownerName = ownerName;
this.balance = initialBalance;
}
// Public getters and setters
public String getAccountNumber() {
return accountNumber;
}
public double getBalance() {
return balance;
}
public String getOwnerName() {
return ownerName;
}
public void setOwnerName(String ownerName) {
if (ownerName != null && !ownerName.trim().isEmpty()) {
this.ownerName = ownerName;
}
}
// Public methods for operations
public void deposit(double amount) {
if (amount > 0) {
balance += amount;
System.out.println("Deposited: {{content}}quot; + amount);
}
}
public void withdraw(double amount) {
if (amount > 0 && amount <= balance) {
balance -= amount;
System.out.println("Withdrew: {{content}}quot; + amount);
} else {
System.out.println("Invalid withdrawal amount");
}
}
}
Benefits of Encapsulation
javapublic class Student {
private String name;
private int age;
private double gpa;
public Student(String name, int age) {
this.name = name;
setAge(age); // Use setter for validation
this.gpa = 0.0;
}
// Validation in setters
public void setAge(int age) {
if (age >= 0 && age <= 120) {
this.age = age;
} else {
throw new IllegalArgumentException("Invalid age");
}
}
public void setGpa(double gpa) {
if (gpa >= 0.0 && gpa <= 4.0) {
this.gpa = gpa;
} else {
throw new IllegalArgumentException("GPA must be between 0.0 and 4.0");
}
}
// Read-only properties (no setters)
public String getName() {
return name;
}
public int getAge() {
return age;
}
public double getGpa() {
return gpa;
}
}
Abstraction
Abstraction focuses on essential features while hiding implementation details.
Abstract Classes
java// Abstract class - cannot be instantiated
abstract class Vehicle {
protected String brand;
protected int speed;
public Vehicle(String brand) {
this.brand = brand;
this.speed = 0;
}
// Abstract method - must be implemented by subclasses
public abstract void start();
public abstract void stop();
// Concrete method
public void displayInfo() {
System.out.println("Brand: " + brand + ", Speed: " + speed + " km/h");
}
// Can have concrete methods with implementation
public void accelerate(int increment) {
speed += increment;
System.out.println("Accelerating to " + speed + " km/h");
}
}
class Car extends Vehicle {
private int doors;
public Car(String brand, int doors) {
super(brand);
this.doors = doors;
}
@Override
public void start() {
System.out.println("Car is starting with key ignition");
speed = 10;
}
@Override
public void stop() {
System.out.println("Car is stopping with brakes");
speed = 0;
}
}
class Motorcycle extends Vehicle {
public Motorcycle(String brand) {
super(brand);
}
@Override
public void start() {
System.out.println("Motorcycle is starting with kick start");
speed = 5;
}
@Override
public void stop() {
System.out.println("Motorcycle is stopping");
speed = 0;
}
}
Interfaces
java// Interface - defines contract without implementation
interface Drawable {
void draw(); // Abstract method
double getArea(); // Abstract method
// Default method (Java 8+)
default String getDescription() {
return "This is a drawable object";
}
// Static method (Java 8+)
static boolean isValidSize(double size) {
return size > 0;
}
}
interface Resizable {
void resize(double factor);
}
// Class implementing multiple interfaces
class Circle implements Drawable, Resizable {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
public void draw() {
System.out.println("Drawing a circle with radius " + radius);
}
@Override
public double getArea() {
return Math.PI * radius * radius;
}
@Override
public void resize(double factor) {
radius *= factor;
System.out.println("Circle resized to radius " + radius);
}
}
Exceptions Introduction
Exceptions handle runtime errors and exceptional conditions in a structured way.
Exception Hierarchy
java// Checked exceptions - must be handled or declared
IOException, SQLException, ClassNotFoundException
// Unchecked exceptions (RuntimeException)
NullPointerException, ArrayIndexOutOfBoundsException,
IllegalArgumentException, ArithmeticException
// Error - serious system problems
OutOfMemoryError, StackOverflowError
Common Exceptions
java// NullPointerException
String str = null;
// System.out.println(str.length()); // Throws NullPointerException
// ArrayIndexOutOfBoundsException
int[] arr = {1, 2, 3};
// System.out.println(arr[5]); // Throws ArrayIndexOutOfBoundsException
// ArithmeticException
int a = 10;
// int b = a / 0; // Throws ArithmeticException
// NumberFormatException
String numStr = "abc";
// int num = Integer.parseInt(numStr); // Throws NumberFormatException
// ClassCastException
Object obj = "Hello";
// Integer num = (Integer) obj; // Throws ClassCastException
Throwing Exceptions
javapublic class Calculator {
public static double divide(double a, double b) {
if (b == 0) {
throw new ArithmeticException("Division by zero is not allowed");
}
return a / b;
}
public static int factorial(int n) {
if (n < 0) {
throw new IllegalArgumentException("Factorial is not defined for negative numbers");
}
if (n == 0) return 1;
return n * factorial(n - 1);
}
}
// Usage
try {
double result = Calculator.divide(10, 0);
} catch (ArithmeticException e) {
System.out.println("Error: " + e.getMessage());
}
Try-Catch Blocks
Try-catch blocks handle exceptions gracefully without terminating the program.
Basic Try-Catch
javatry {
int[] numbers = {1, 2, 3};
System.out.println(numbers[5]); // This will throw exception
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Array index is out of bounds!");
System.out.println("Error message: " + e.getMessage());
}
Multiple Catch Blocks
javatry {
String str = null;
int num = Integer.parseInt("abc");
System.out.println(str.length());
} catch (NullPointerException e) {
System.out.println("String is null!");
} catch (NumberFormatException e) {
System.out.println("Invalid number format!");
} catch (Exception e) {
System.out.println("Some other error occurred: " + e.getMessage());
}
Try-With-Resources
java// Automatically closes resources
try (FileInputStream fis = new FileInputStream("file.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(fis))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
System.out.println("Error reading file: " + e.getMessage());
}
Finally Block
javaFileInputStream fis = null;
try {
fis = new FileInputStream("file.txt");
// Read file operations
} catch (IOException e) {
System.out.println("Error: " + e.getMessage());
} finally {
// Always executes, used for cleanup
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
System.out.println("Error closing file: " + e.getMessage());
}
}
System.out.println("Finally block executed");
}
Custom Exceptions
Custom exceptions allow you to create application-specific exception types.
Creating Custom Exceptions
java// Checked exception
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;
}
}
// Unchecked exception
class InvalidAgeException extends RuntimeException {
private int invalidAge;
public InvalidAgeException(int invalidAge) {
super("Invalid age: " + invalidAge + ". Age must be between 0 and 120.");
this.invalidAge = invalidAge;
}
public int getInvalidAge() {
return invalidAge;
}
}
Using Custom Exceptions
javaclass BankAccount {
private double balance;
public BankAccount(double initialBalance) {
this.balance = initialBalance;
}
public void withdraw(double amount) throws InsufficientFundsException {
if (amount > balance) {
throw new InsufficientFundsException(amount, balance);
}
balance -= amount;
System.out.println("Withdrew: " + amount);
}
}
class Person {
private String name;
private int age;
public Person(String name, int age) {
if (age < 0 || age > 120) {
throw new InvalidAgeException(age);
}
this.name = name;
this.age = age;
}
}
// Usage
try {
BankAccount account = new BankAccount(1000);
account.withdraw(1500); // Throws InsufficientFundsException
} catch (InsufficientFundsException e) {
System.out.println(e.getMessage());
System.out.println("Shortfall: " + (e.getAmount() - e.getBalance()));
}
// Unchecked exception doesn't require try-catch
Person person = new Person("John", 150); // Throws InvalidAgeException
Advanced Java Concepts
Advanced Java features for writing efficient, modern code.
Generics
java// Generic class
class Box<T> {
private T content;
public void setContent(T content) {
this.content = content;
}
public T getContent() {
return content;
}
}
// Generic methods
class Utilities {
public static <T> void printArray(T[] array) {
for (T element : array) {
System.out.print(element + " ");
}
System.out.println();
}
public static <T extends Comparable<T>> T findMax(T[] array) {
if (array == null || array.length == 0) return null;
T max = array[0];
for (T element : array) {
if (element.compareTo(max) > 0) {
max = element;
}
}
return max;
}
}
// Usage
Box<String> stringBox = new Box<>();
stringBox.setContent("Hello");
Box<Integer> intBox = new Box<>();
intBox.setContent(42);
Integer[] numbers = {1, 5, 3, 9, 2};
System.out.println("Max: " + Utilities.findMax(numbers));
Lambda Expressions
javaimport java.util.Arrays;
import java.util.List;
import java.util.function.*;
// Functional interfaces with lambdas
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "Diana");
// Using lambda with forEach
names.forEach(name -> System.out.println(name));
// Using method reference
names.forEach(System.out::println);
// Filtering with lambda
names.stream()
.filter(name -> name.startsWith("A"))
.forEach(System.out::println);
// Custom functional interface
@FunctionalInterface
interface StringProcessor {
String process(String input);
}
StringProcessor toUpper = s -> s.toUpperCase();
StringProcessor addExclamation = s -> s + "!";
System.out.println(toUpper.process("hello")); // HELLO
System.out.println(addExclamation.process("hello")); // hello!
Stream API
javaimport java.util.*;
import java.util.stream.*;
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// Filter even numbers, square them, and collect to list
List<Integer> result = numbers.stream()
.filter(n -> n % 2 == 0)
.map(n -> n * n)
.collect(Collectors.toList());
System.out.println(result); // [4, 16, 36, 64, 100]
// Reduction operations
int sum = numbers.stream().reduce(0, Integer::sum);
Optional<Integer> max = numbers.stream().max(Integer::compare);
System.out.println("Sum: " + sum); // 55
System.out.println("Max: " + max.get()); // 10
// Grouping
List<String> words = Arrays.asList("apple", "banana", "cherry", "date");
Map<Integer, List<String>> groupedByLength = words.stream()
.collect(Collectors.groupingBy(String::length));
System.out.println(groupedByLength); // {5=[apple], 6=[banana, cherry], 4=[date]}