Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
15 views

Core_Java

The document outlines essential Core Java best practices and topics for interview preparation, including Java basics, OOP principles, exception handling, multithreading, and Java 8 features. It emphasizes key concepts such as encapsulation, inheritance, polymorphism, and abstraction, along with practical examples and coding practices. Additionally, it covers memory management, JDBC, design patterns, and common coding questions relevant for Java developers.

Uploaded by

vksv08
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
15 views

Core_Java

The document outlines essential Core Java best practices and topics for interview preparation, including Java basics, OOP principles, exception handling, multithreading, and Java 8 features. It emphasizes key concepts such as encapsulation, inheritance, polymorphism, and abstraction, along with practical examples and coding practices. Additionally, it covers memory management, JDBC, design patterns, and common coding questions relevant for Java developers.

Uploaded by

vksv08
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 123

Core Java Best Practices

If you're preparing for interviews or want to strengthen your Core Java knowledge, here are
the most important topics to focus on:

1. Java Basics
Features of Java

JDK, JRE, and JVM

Data Types, Variables, and Operators

Type Casting (Widening & Narrowing)

Control Statements (if-else, switch, loops)

2. OOPs (Object-Oriented Programming)


Four Pillars of OOP:

Encapsulation

Inheritance

Polymorphism (Method Overloading & Overriding)

Abstraction (Interfaces & Abstract Classes)

Other OOP Concepts:

this and super keywords

final keyword (class, method, variable)

Static vs Non-static members

Access Modifiers (private, protected, public, default)

1/5
3. Strings
String Pool, Immutability

String Manipulation ( String , StringBuilder , StringBuffer )

Important String Methods

String Comparisons ( == , .equals() , .compareTo() )

4. Arrays and Collections Framework (Java.util)


Arrays: Declaration, Initialization, Multi-Dimensional Arrays

Collections Framework:

List ( ArrayList , LinkedList , Vector )

Set ( HashSet , TreeSet , LinkedHashSet )

Map ( HashMap , TreeMap , LinkedHashMap )

Queue ( PriorityQueue , Deque )

Comparable vs Comparator

5. Exception Handling
Types of Exceptions (Checked, Unchecked)

try , catch , finally , throw , throws

Custom Exceptions

6. Multithreading & Concurrency


Thread Lifecycle

Creating Threads ( Thread class, Runnable interface)

2/5
Synchronization (Locks, synchronized keyword)

Deadlock and Thread Communication

7. File Handling (Java I/O)


File Reading & Writing ( FileReader , FileWriter , BufferedReader , BufferedWriter )

Serialization & Deserialization

8. Java 8 Features
Functional Interfaces & Lambda Expressions

Stream API

Method References

Default & Static Methods in Interfaces

Optional Class

9. JDBC (Java Database Connectivity)


Steps to connect Java with a Database

JDBC Drivers

CRUD Operations with JDBC

10. Design Patterns (Basic Understanding)


Singleton Pattern

Factory Pattern

3/5
Builder Pattern

Observer Pattern

11. Memory Management & Garbage Collection


Stack vs Heap Memory

Garbage Collection Mechanisms

Weak References & Soft References

12. Reflection API & Annotations


@Override , @FunctionalInterface , @SuppressWarnings , @Deprecated

Creating Custom Annotations

13. Inner Classes


Regular Inner Class

Static Nested Class

Anonymous Inner Class

Local Inner Class

14. Java Networking


Sockets & HTTP Communication

URL & URLConnection

4/5
15. Java Security
Hashing (MD5, SHA)

Encryption & Decryption (AES, RSA)

16. Java Interview-Specific Topics


Difference Between:

== vs .equals()

StringBuffer vs StringBuilder

ArrayList vs LinkedList

HashMap vs Hashtable

final , finally , finalize

Common Coding Questions:

Fibonacci Series

Palindrome String/Number

Sorting Algorithms (Bubble, Quick, Merge)

Find Duplicates in Array

Reverse a String

Next Steps?
Let me know if you need in-depth explanations on any of these topics! 😊

5/5
Core Java Best Practices

1. Java Basics
1.1 Introduction to Java
Java is a high-level, object-oriented programming language developed by Sun
Microsystems in 1995 and later acquired by Oracle Corporation. It is platform-independent
and widely used for building enterprise applications, mobile apps, and web applications.

Why Java?
✔ Write Once, Run Anywhere (WORA) – Java applications can run on any platform with a
JVM.
✔ Robust and Secure – Java provides strong memory management and built-in security
features.
✔ Multithreading Support – Java can execute multiple tasks simultaneously.
✔ Rich API & Libraries – Comes with a vast set of prebuilt functions.

2. Features of Java
1️⃣ Platform Independence
Java code is compiled into bytecode, which can run on any OS with a JVM (Java Virtual
Machine).

Example:
java

System.out.println("Java is platform-independent!");

2️⃣ Object-Oriented
Java follows OOP principles: Encapsulation, Inheritance, Polymorphism, and Abstraction.

3️⃣ Automatic Memory Management


1/8
Java has Garbage Collection, which automatically removes unused objects.

4️⃣ Multithreading
Java supports multithreading, allowing efficient CPU utilization.

5️⃣ Secure
Java does not use pointers, reducing vulnerabilities.

It provides bytecode verification and runtime security checks.

6️⃣ Rich Standard Library


Java comes with extensive libraries such as Collections, JDBC, Networking, I/O, etc..

3. JDK, JRE, and JVM


Component Description

JDK (Java Development Kit) Includes JRE + development tools (compiler, debugger) to develop
Java programs.

JRE (Java Runtime Contains JVM + libraries required to run Java applications.
Environment)

JVM (Java Virtual Machine) Converts bytecode into machine code for execution on different
platforms.

Execution Flow:
1️⃣ Java Source Code ( ) .java
➡ Compiled by javaccompiler
2️⃣ Bytecode ( file)
.class
➡ Executed by JVM ( java command)

Example:

sh

javac HelloWorld.java # Compile

2/8
java HelloWorld # Run

4. Data Types, Variables, and


Operators
4.1 Data Types in Java
Java has two categories of data types:

Data Type Category Example

Primitive Basic types int , char , double , boolean

Non-Primitive Objects String , Array , Class , Interface

Primitive Data Types


Data Type Size Default Value Example

byte 1 byte 0 byte b = 100;

short 2 bytes 0 short s = 32000;

int 4 bytes 0 int i = 100000;

long 8 bytes 0L long l = 9999999999L;

float 4 bytes 0.0f float f = 10.5f;

double 8 bytes 0.0d double d = 99.99;

char 2 bytes '\u0000' char c = 'A';

boolean 1 bit false boolean flag = true;

Non-Primitive Data Types


Example: String , Array , Class , Interface

java

String name = "Java";


int[] numbers = {1, 2, 3};

3/8
4.2 Variables in Java
A variable is a name given to a memory location that stores data.

Types of Variables
Type Scope Example

Local Variable Inside method/block int age = 25;

Instance Variable Inside a class but outside a method String name;

Static Variable Shared among all objects static int count;

Example:

java

class Example {
int instanceVar = 10; // Instance Variable
static int staticVar = 20; // Static Variable

public void method() {


int localVar = 30; // Local Variable
}
}

4.3 Operators in Java


Java provides operators to perform operations on variables.

Types of Operators
Operator Type Example

Arithmetic Operators +, -, *, /, %

Relational Operators == , != , > , < , >= , <=

Logical Operators && , `

Bitwise Operators & ,`

4/8
Operator Type Example

Assignment Operators = , += , -= , *= , /=

Unary Operators ++ , --

Ternary Operator ? :

Example:

java

int a = 10, b = 20;


System.out.println(a + b); // 30 (Arithmetic)
System.out.println(a > b); // false (Relational)
System.out.println(a < b && b > 15); // true (Logical)

5. Type Casting in Java


Type casting converts one data type into another.

5.1 Widening (Implicit Type Casting)


Small to large data type (automatic conversion).

java

int num = 10;


double d = num; // Implicit conversion
System.out.println(d); // Output: 10.0

5.2 Narrowing (Explicit Type Casting)


Large to small data type (manual conversion).

java

5/8
double num = 10.5;
int n = (int) num; // Explicit conversion
System.out.println(n); // Output: 10

6. Control Statements
Control statements manage the flow of execution in Java.

6.1 Conditional Statements


(i) if-else Statement
java

int age = 18;


if (age >= 18) {
System.out.println("You can vote!");
} else {
System.out.println("You cannot vote.");
}

(ii) switch Statement


java

int day = 2;
switch (day) {
case 1: System.out.println("Monday"); break;
case 2: System.out.println("Tuesday"); break;
default: System.out.println("Invalid day");
}

6/8
6.2 Looping Statements
Loops execute a block of code multiple times.

(i) for Loop

java

for (int i = 1; i <= 5; i++) {


System.out.println("Count: " + i);
}

(ii) while Loop


java

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

(iii) do-while Loop

java

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

Conclusion
✔ Java provides strong features like platform independence, security, and OOP principles.
✔ Data types, variables, and operators are fundamental building blocks.
✔ Control statements allow us to manage the program flow efficiently.

7/8
Next Topic: Do you want to explore OOP concepts (Classes, Objects, Inheritance,
Polymorphism)? 🚀

8/8
Core Java Best Practices

Object-Oriented Programming (OOP)


in Java
1. Introduction to OOP
Object-Oriented Programming (OOP) is a programming paradigm that uses objects and
classes to design software applications. Java is fully object-oriented because it supports
OOP principles.

Benefits of OOP
✔ Modularity – Code is divided into smaller parts (objects and classes).
✔ Reusability – Inheritance allows using existing code.
✔ Scalability – OOP allows easy modifications and extensions.
✔ Security – Encapsulation hides data and methods.

2. Four Pillars of OOP


2.1 Encapsulation
Encapsulation is hiding the data (variables) inside a class and allowing controlled access
through getters and setters.

Example: Encapsulation in a Bank Account

java

class BankAccount {
private double balance; // Private variable (hidden from outside access)

public void deposit(double amount) {


if (amount > 0) {
balance += amount;

1/9
}
}

public double getBalance() {


return balance;
}
}

public class Main {


public static void main(String[] args) {
BankAccount acc = new BankAccount();
acc.deposit(1000);
System.out.println("Balance: " + acc.getBalance());
}
}

✔ Private data cannot be accessed directly from outside the class.


✔ Public methods provide controlled access.

2.2 Inheritance
Inheritance allows a child class to inherit properties and behavior from a parent class
using the extends keyword.

Example: Car class inherits Vehicle class

java

class Vehicle {
void move() {
System.out.println("Vehicle is moving...");
}
}

class Car extends Vehicle {


void speed() {
System.out.println("Car is speeding...");
}
}

2/9
public class Main {
public static void main(String[] args) {
Car myCar = new Car();
myCar.move(); // Inherited from Vehicle
myCar.speed(); // Defined in Car
}
}

✔ Code reuse – The Car class does not need to redefine the move() method.
✔ Hierarchy – Inheritance forms a relationship between classes.

2.3 Polymorphism
Polymorphism means "many forms", allowing the same method to perform different tasks.

(i) Method Overloading (Compile-time Polymorphism)


Same method name but different parameters in the same class.

java

class MathOperations {
int add(int a, int b) {
return a + b;
}

double add(double a, double b) {


return a + b;
}
}

public class Main {


public static void main(String[] args) {
MathOperations obj = new MathOperations();
System.out.println(obj.add(5, 3)); // Calls int version
System.out.println(obj.add(5.5, 2.2)); // Calls double version
}
}

3/9
(ii) Method Overriding (Runtime Polymorphism)
Child class provides a new implementation for an inherited method.

java

class Animal {
void sound() {
System.out.println("Animals make sounds");
}
}

class Dog extends Animal {


@Override
void sound() {
System.out.println("Dog barks");
}
}

public class Main {


public static void main(String[] args) {
Animal myDog = new Dog(); // Upcasting
myDog.sound(); // Calls Dog's sound() method
}
}

✔ Method Overriding enables runtime behavior change.


✔ Dynamic Method Dispatch – The overridden method is called based on the object type.

2.4 Abstraction
Abstraction hides implementation details and shows only essential features.

(i) Using Abstract Classes


Abstract classes can have both abstract (unimplemented) and concrete methods.

4/9
java

abstract class Vehicle {


abstract void start(); // Abstract method (no implementation)

void stop() { // Concrete method


System.out.println("Vehicle stopped.");
}
}

class Car extends Vehicle {


@Override
void start() {
System.out.println("Car started with a key");
}
}

public class Main {


public static void main(String[] args) {
Vehicle myCar = new Car();
myCar.start();
myCar.stop();
}
}

(ii) Using Interfaces


Interfaces contain only abstract methods (until Java 8).

A class can implement multiple interfaces.

java

interface Engine {
void start();
}

class Bike implements Engine {


public void start() {
System.out.println("Bike started with self-start");

5/9
}
}

public class Main {


public static void main(String[] args) {
Bike myBike = new Bike();
myBike.start();
}
}

✔ Interfaces support multiple inheritance.


✔ They provide full abstraction since they contain no concrete methods.

3. Other OOP Concepts


3.1 this Keyword
Refers to the current object.

Used to avoid variable shadowing.

java

class Example {
int x;

Example(int x) {
this.x = x; // Resolves variable shadowing
}
}

3.2 super Keyword


Refers to the parent class.

6/9
Used to call parent class methods and constructors.

java

class Parent {
Parent() {
System.out.println("Parent Constructor");
}
}

class Child extends Parent {


Child() {
super(); // Calls Parent() constructor
System.out.println("Child Constructor");
}
}

public class Main {


public static void main(String[] args) {
Child obj = new Child();
}
}

✔ super() must be the first statement in the constructor.

3.3 final Keyword


Usage Example

Final Variable (Cannot change value) final int PI = 3.14;

Final Method (Cannot be overridden) final void display() {}

Final Class (Cannot be inherited) final class Animal {}

Example:

java

final class Animal {} // Cannot be extended by any other class

7/9
3.4 Static vs Non-Static Members
Feature Static Non-Static

Memory Allocation Class level Object level

Access ClassName.method() object.method()

Example static int x; int y;

Example:

java

class Example {
static int staticVar = 10; // Shared across objects
int instanceVar = 20; // Separate for each object
}

3.5 Access Modifiers


Accessible Within Same Outside Package Outside
Modifier Class Package (Subclass) Package

private ✅ ❌ ❌ ❌
default ✅ ✅ ❌ ❌
protected ✅ ✅ ✅ ❌
public ✅ ✅ ✅ ✅
Example:

java

public class Example {


private int x; // Cannot be accessed outside
protected int y; // Can be accessed in subclasses
public int z; // Can be accessed anywhere
}

8/9
Conclusion
✔ Java follows four OOP principles: Encapsulation, Inheritance, Polymorphism, and
Abstraction.
✔ Additional OOP concepts like this, super, final, static, and access modifiers improve code
structure.

Next Topic: Do you want to explore Java Collections (List, Set, Map, etc.) or Multithreading
in Java? 🚀

9/9
Core Java Best Practices

Java Strings - In-depth Explanation


Strings are one of the most commonly used data types in Java. Java provides the String
class for handling text-based data efficiently.

1. What is a String in Java?


A String in Java is a sequence of characters.

It is immutable, meaning once created, its value cannot be changed.

The String class is part of java.lang package.

Example: Creating Strings


java

public class StringExample {


public static void main(String[] args) {
String str1 = "Hello"; // String literal
String str2 = new String("World"); // Using new keyword
System.out.println(str1 + " " + str2);
}
}

2. String Pool & Immutability


2.1 What is String Pool?

1/8
The String Pool is a special memory area inside the Heap where Java stores String
literals.

If a String already exists in the pool, Java returns the same reference instead of creating
a new one.

Example: String Pool Behavior

java

public class StringPoolExample {


public static void main(String[] args) {
String s1 = "Java"; // Stored in String pool
String s2 = "Java"; // References the same object
String s3 = new String("Java"); // Creates a new object

System.out.println(s1 == s2); // true (same reference)


System.out.println(s1 == s3); // false (different objects)
}
}

✔ Strings created using literals are stored in the String Pool.


✔ Strings created with new String("...") are stored in Heap memory separately.

2.2 Why are Strings Immutable?


In Java, Strings are immutable to ensure security, caching, and thread safety.

Any modification creates a new object, instead of changing the original.

Example: String Immutability

java

public class StringImmutableExample {


public static void main(String[] args) {
String s = "Java";
s.concat(" Programming"); // Creates a new String, but the reference isn't
updated
System.out.println(s); // Output: Java (unchanged)

2/8
s = s.concat(" Programming"); // Now, `s` points to the new object
System.out.println(s); // Output: Java Programming
}
}

✔ The original s remains unchanged after calling concat() .


✔ A new object is created with "Java Programming" .

3. String Manipulation
Java provides three classes for String manipulation:

1. String – Immutable

2. StringBuilder – Mutable, not thread-safe

3. StringBuffer – Mutable, thread-safe

3.1 String Class (Immutable)


Every modification creates a new object.

Used when Strings are rarely changed.

Example: Concatenation using String

java

public class StringExample {


public static void main(String[] args) {
String str = "Hello";
str = str + " World"; // Creates a new object
System.out.println(str);
}
}

3/8
3.2 StringBuilder (Mutable, Fast)
Faster than StringBuffer since it's not synchronized.

Used when String modifications are frequent.

Example: Using StringBuilder

java

public class StringBuilderExample {


public static void main(String[] args) {
StringBuilder sb = new StringBuilder("Hello");
sb.append(" World");
System.out.println(sb); // Output: Hello World
}
}

✔ StringBuilder modifies the same object, improving performance.

3.3 StringBuffer (Mutable, Thread-Safe)


Thread-safe but slower than StringBuilder .

Used in multi-threaded applications.

Example: Using StringBuffer

java

public class StringBufferExample {


public static void main(String[] args) {
StringBuffer sb = new StringBuffer("Hello");
sb.append(" World");
System.out.println(sb); // Output: Hello World
}
}

4/8
✔ StringBuffer ensures data consistency in multi-threaded environments.

4. Important String Methods


Method Description Example

length() Returns length of the "Hello".length() → 5


string

charAt(index) Returns character at "Java".charAt(2) → 'v'


given index

substring(start, Extracts a substring "Hello".substring(1, 4) → "ell"


end)

toUpperCase() Converts to uppercase "java".toUpperCase() → "JAVA"

toLowerCase() Converts to lowercase "JAVA".toLowerCase() → "java"

trim() Removes leading/trailing " Hello ".trim() → "Hello"


spaces

replace(old, new) Replaces characters "Hello".replace('H', 'J') → "Jello"

split(regex) Splits a string "apple,orange".split(",") → ["apple",


"orange"]

contains(str) Checks if substring exists "Hello".contains("He") → true

indexOf(str) Returns first occurrence "Java".indexOf("v") → 2


index

Example: Using String Methods

java

public class StringMethodsExample {


public static void main(String[] args) {
String str = " Hello Java ";
System.out.println(str.trim()); // Removes spaces
System.out.println(str.toUpperCase()); // Converts to uppercase
System.out.println(str.replace("Java", "World")); // Replaces text
}
}

5/8
5. String Comparisons
Java provides three ways to compare Strings:

5.1 Using == (Reference Comparison)


Compares memory addresses, not values.

java

String s1 = "Java";
String s2 = "Java";
String s3 = new String("Java");

System.out.println(s1 == s2); // true (same reference)


System.out.println(s1 == s3); // false (different objects)

✔ Use == only for reference checks.

5.2 Using .equals() (Value Comparison)


Compares actual content of Strings.

java

String s1 = "Java";
String s2 = new String("Java");

System.out.println(s1.equals(s2)); // true (same content)

✔ Always use .equals() to compare String content.

6/8
5.3 Using .compareTo() (Lexicographical Comparison)
Used for sorting Strings based on ASCII values.

Returns:

0 → Both strings are equal

< 0 → First string is smaller

> 0 → First string is greater

java

public class StringCompareExample {


public static void main(String[] args) {
String s1 = "Apple";
String s2 = "Banana";

System.out.println(s1.compareTo(s2)); // Output: -1 (Apple < Banana)


}
}

✔ Useful for sorting Strings in Java.

Conclusion
✔ Strings in Java are immutable, meaning their value cannot be changed.
✔ Use StringBuilder or StringBuffer for efficient modifications.
✔ Use .equals() for content comparison, not == .
✔ Use .compareTo() for lexicographical comparison.

Next Topic: Do you want to explore Java Collections (List,


Set, Map, etc.) or Exception Handling in Java? 🚀
7/8
8/8
Core Java Best Practices
Update memory?

Java Arrays and Collections


Framework - In-depth Explanation

1. Arrays in Java
An array is a fixed-size, ordered collection of elements of the same data type.

1.1 Declaring and Initializing Arrays

java

// Declaration
int[] arr1; // Recommended
int arr2[]; // Also valid

// Initialization
int[] numbers = {1, 2, 3, 4, 5}; // Using array literal
int[] values = new int[5]; // Creating an array of size 5

// Assigning values
values[0] = 10;
values[1] = 20;
System.out.println(values[1]); // Output: 20

1.2 Multi-Dimensional Arrays

java

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

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

✔ Arrays have fixed size, meaning you cannot dynamically resize them.

1/9
2. Collections Framework
The Java Collections Framework (JCF) provides dynamic and flexible data structures.

Key Interfaces in JCF


Interface Description

List Ordered collection (allows duplicates)

Set Unordered collection (no duplicates)

Map Key-value pairs (unique keys)

Queue FIFO (First-In-First-Out) collection

3. List Interface (Ordered, Allows Duplicates)


3.1 ArrayList (Dynamic Array)
✔ Fast read, slow insert/delete (uses a dynamic array internally).

java

import java.util.*;

public class ArrayListExample {


public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("Java");
list.add("Python");
list.add("Java");
list.remove("Python");

System.out.println(list); // Output: [Java, Java]


}
}

2/9
3.2 LinkedList (Doubly Linked List)
✔ Fast insert/delete, slow read.

java

import java.util.*;

public class LinkedListExample {


public static void main(String[] args) {
List<Integer> list = new LinkedList<>();
list.add(10);
list.add(20);
list.addFirst(5);

System.out.println(list); // Output: [5, 10, 20]


}
}

3.3 Vector (Thread-Safe)


✔ Similar to ArrayList , but synchronized.

java

import java.util.*;

public class VectorExample {


public static void main(String[] args) {
Vector<Integer> vec = new Vector<>();
vec.add(100);
vec.add(200);

System.out.println(vec); // Output: [100, 200]


}
}

3/9
4. Set Interface (Unordered, No Duplicates)
4.1 HashSet (No Order, Fast Access)
✔ Uses HashMap internally.

java

import java.util.*;

public class HashSetExample {


public static void main(String[] args) {
Set<String> set = new HashSet<>();
set.add("Java");
set.add("Python");
set.add("Java"); // Duplicate, will be ignored

System.out.println(set); // Output: [Java, Python] (Order may vary)


}
}

4.2 TreeSet (Sorted Order)


✔ Uses Red-Black Tree (sorted, slower than HashSet ).

java

import java.util.*;

public class TreeSetExample {


public static void main(String[] args) {
Set<Integer> set = new TreeSet<>();
set.add(30);
set.add(10);
set.add(20);

System.out.println(set); // Output: [10, 20, 30] (Sorted)


}
}

4/9
4.3 LinkedHashSet (Insertion Order Maintained)

java

import java.util.*;

public class LinkedHashSetExample {


public static void main(String[] args) {
Set<String> set = new LinkedHashSet<>();
set.add("Java");
set.add("Python");
set.add("C++");

System.out.println(set); // Output: [Java, Python, C++]


}
}

5. Map Interface (Key-Value Pairs, Unique Keys)


5.1 HashMap (Fast, No Order)
✔ Uses Hashing (allows null keys).

java

import java.util.*;

public class HashMapExample {


public static void main(String[] args) {
Map<Integer, String> map = new HashMap<>();
map.put(1, "Java");
map.put(2, "Python");

System.out.println(map.get(1)); // Output: Java


}
}

5/9
5.2 TreeMap (Sorted by Key)
✔ Uses Red-Black Tree.

java

import java.util.*;

public class TreeMapExample {


public static void main(String[] args) {
Map<Integer, String> map = new TreeMap<>();
map.put(3, "C++");
map.put(1, "Java");
map.put(2, "Python");

System.out.println(map); // Output: {1=Java, 2=Python, 3=C++}


}
}

5.3 LinkedHashMap (Insertion Order Maintained)


java

import java.util.*;

public class LinkedHashMapExample {


public static void main(String[] args) {
Map<String, Integer> map = new LinkedHashMap<>();
map.put("Apple", 50);
map.put("Banana", 30);

System.out.println(map); // Output: {Apple=50, Banana=30}


}
}

6/9
6. Queue Interface (FIFO - First In First Out)
6.1 PriorityQueue (Elements in Natural Order)
✔ Uses Heap Data Structure.

java

import java.util.*;

public class PriorityQueueExample {


public static void main(String[] args) {
Queue<Integer> pq = new PriorityQueue<>();
pq.add(30);
pq.add(10);
pq.add(20);

System.out.println(pq.poll()); // Output: 10 (Smallest element)


}
}

6.2 Deque (Double-Ended Queue)


✔ Allows insert/remove at both ends.

java

import java.util.*;

public class DequeExample {


public static void main(String[] args) {
Deque<String> dq = new ArrayDeque<>();
dq.addFirst("First");
dq.addLast("Last");

System.out.println(dq.pollFirst()); // Output: First


}
}

7/9
7. Comparable vs Comparator
✔ Comparable is used for natural ordering ( compareTo() ).
✔ Comparator is used for custom sorting ( compare() ).

7.1 Comparable (Default Sorting)

java

import java.util.*;

class Student implements Comparable<Student> {


int id;
String name;

Student(int id, String name) {


this.id = id;
this.name = name;
}

public int compareTo(Student s) {


return this.id - s.id; // Ascending order
}
}

public class ComparableExample {


public static void main(String[] args) {
List<Student> list = new ArrayList<>();
list.add(new Student(2, "Alice"));
list.add(new Student(1, "Bob"));

Collections.sort(list); // Uses compareTo()


}
}

7.2 Comparator (Custom Sorting)

8/9
java

import java.util.*;

class Student {
int id;
String name;

Student(int id, String name) {


this.id = id;
this.name = name;
}
}

class NameComparator implements Comparator<Student> {


public int compare(Student s1, Student s2) {
return s1.name.compareTo(s2.name); // Sort by name
}
}

public class ComparatorExample {


public static void main(String[] args) {
List<Student> list = new ArrayList<>();
list.add(new Student(2, "Alice"));
list.add(new Student(1, "Bob"));

Collections.sort(list, new NameComparator());


}
}

Next Topic: Do you want to explore


Exception Handling in Java? 🚀

9/9
Core Java Best Practices

Java Exception Handling - In-depth


Explanation

1. What is Exception Handling in Java?


An exception is an unwanted or unexpected event that occurs during program execution,
disrupting the normal flow. Exception Handling ensures that the program runs smoothly,
even when unexpected errors occur.

Example: Exception Without Handling

java

public class ExceptionExample {


public static void main(String[] args) {
int num = 10, denom = 0;
int result = num / denom; // Causes ArithmeticException
System.out.println(result);
}
}

💥 Error: Exception in thread "main" java.lang.ArithmeticException: / by zero

2. Types of Exceptions in Java


Java exceptions are categorized into:

Type Description Examples

Checked Must be handled using try- IOException , SQLException


Exceptions catch or throws . Compiler
checks these exceptions.

1/6
Type Description Examples

Unchecked Runtime exceptions caused by NullPointerException ,


Exceptions logic errors. Compiler doesn't ArrayIndexOutOfBoundsException ,
check them. ArithmeticException

Errors Critical issues that cannot be StackOverflowError , OutOfMemoryError


handled at runtime.

3. Handling Exceptions in Java


3.1 try and catch Blocks
✔ The try block contains risky code.
✔ The catch block handles exceptions if they occur.

java

public class TryCatchExample {


public static void main(String[] args) {
try {
int num = 10, denom = 0;
int result = num / denom; // Exception occurs here
System.out.println(result);
} catch (ArithmeticException e) {
System.out.println("Cannot divide by zero!");
}
}
}

🛡 Output: Cannot divide by zero!

3.2 finally Block


✔ Executes always, regardless of whether an exception occurs or not.
✔ Used for resource cleanup (e.g., closing database connections, files).

java

2/6
public class FinallyExample {
public static void main(String[] args) {
try {
int[] arr = {1, 2, 3};
System.out.println(arr[5]); // Throws ArrayIndexOutOfBoundsException
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Index out of bounds!");
} finally {
System.out.println("This will always execute.");
}
}
}

🛡 Output:

pgsql

Index out of bounds!


This will always execute.

4. throw and throws in Java


4.1 throw (Manually Throwing an Exception)
✔ Used to explicitly throw an exception.
✔ Typically used in custom validation logic.

java

public class ThrowExample {


public static void validateAge(int age) {
if (age < 18) {
throw new IllegalArgumentException("Age must be 18 or above");
}
System.out.println("Access granted!");
}

public static void main(String[] args) {

3/6
validateAge(16); // Throws IllegalArgumentException
}
}

🛡 Output: Exception in thread "main" java.lang.IllegalArgumentException: Age must


be 18 or above

4.2 throws (Declaring Exceptions)


✔ Used in method signatures to indicate that a method may throw exceptions.
✔ Calling code must handle or propagate the exception.

java

import java.io.*;

public class ThrowsExample {


public static void readFile() throws IOException {
FileReader file = new FileReader("nonexistent.txt"); // May throw
IOException
}

public static void main(String[] args) {


try {
readFile();
} catch (IOException e) {
System.out.println("File not found!");
}
}
}

🛡 Output: File not found!

5. Custom Exceptions

4/6
✔ We can define our own exception classes by extending Exception (for checked
exceptions) or RuntimeException (for unchecked exceptions).

Example: Custom Exception for Invalid Age

java

class InvalidAgeException extends Exception {


public InvalidAgeException(String message) {
super(message);
}
}

public class CustomExceptionExample {


public static void validateAge(int age) throws InvalidAgeException {
if (age < 18) {
throw new InvalidAgeException("You must be at least 18.");
}
System.out.println("Welcome!");
}

public static void main(String[] args) {


try {
validateAge(16);
} catch (InvalidAgeException e) {
System.out.println("Caught Exception: " + e.getMessage());
}
}
}

🛡 Output: Caught Exception: You must be at least 18.

6. Best Practices for Exception Handling


✅ Use Specific Exceptions (e.g., ,
IOException ) instead of generic
SQLException
Exception.
✅ Log Exceptions Properly using instead of printing stack traces.
Logger
✅ Use for Cleanup (e.g., closing files, database connections).
finally

5/6
✅ Avoid Empty Blocks (handle exceptions properly).
catch
✅ Create Custom Exceptions when necessary.

Next Topic: Do you want to explore


Multithreading in Java? 🚀

6/6
Core Java Best Practices

Java Multithreading & Concurrency -


In-depth Explanation

1. What is Multithreading?
Multithreading is a technique where multiple threads (lightweight processes) run
concurrently to achieve parallel execution and improve performance.

Example: Single-threaded vs Multithreaded Execution


Single-threaded Execution (Sequential)

java

public class SingleThreadExample {


public static void main(String[] args) {
System.out.println("Task 1");
System.out.println("Task 2");
System.out.println("Task 3");
}
}

🛡 Output (Always same order):

arduino

Task 1
Task 2
Task 3

Multithreaded Execution (Parallel)

java

1/9
class MyThread extends Thread {
public void run() {
System.out.println("Thread running: " + Thread.currentThread().getName());
}
}

public class MultiThreadExample {


public static void main(String[] args) {
MyThread t1 = new MyThread();
MyThread t2 = new MyThread();
t1.start();
t2.start();
}
}

🛡 Output (Unpredictable Order):

mathematica

Thread running: Thread-0


Thread running: Thread-1

2. Thread Lifecycle in Java


A thread goes through the following states:

State Description

New Thread is created but not started yet.

Runnable Thread is ready to run but waiting for CPU.

Running Thread is executing its task.

Blocked Thread is waiting to acquire a lock.

Waiting Thread is waiting indefinitely for another thread’s signal.

Timed Waiting Thread is waiting for a specific time.

Terminated Thread has finished execution.

Example: Thread Lifecycle

2/9
java

class MyThread extends Thread {


public void run() {
System.out.println("Thread running...");
}
}

public class ThreadLifecycle {


public static void main(String[] args) {
MyThread t = new MyThread();
System.out.println("Thread state: " + t.getState()); // NEW
t.start();
System.out.println("Thread state: " + t.getState()); // RUNNABLE
}
}

3. Creating Threads in Java


There are two ways to create a thread in Java:

3.1 Extending the Thread Class


✔ Override the run() method.
✔ Call start() to begin execution.

java

class MyThread extends Thread {


public void run() {
System.out.println("Thread running...");
}
}

public class ThreadExample {


public static void main(String[] args) {
MyThread t1 = new MyThread();
t1.start();

3/9
}
}

3.2 Implementing the Runnable Interface (Recommended)


✔ More flexible, avoids single inheritance limitation.

java

class MyRunnable implements Runnable {


public void run() {
System.out.println("Thread running...");
}
}

public class RunnableExample {


public static void main(String[] args) {
Thread t1 = new Thread(new MyRunnable());
t1.start();
}
}

4. Synchronization in Java
Problem: When multiple threads access a shared resource, data inconsistency can occur.

4.1 synchronized Keyword


✔ Ensures that only one thread accesses the critical section at a time.

java

class Counter {
private int count = 0;

public synchronized void increment() {


count++;
}

public int getCount() {

4/9
return count;
}
}

public class SynchronizationExample {


public static void main(String[] args) throws InterruptedException {
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: " + counter.getCount());


}
}

🛡 Output: Final count: 2000 (without synchronization, it may give inconsistent results)

4.2 Locks in Java ( ReentrantLock )


✔ Provides better control than synchronized .

java

import java.util.concurrent.locks.*;

class Counter {
private int count = 0;
private final Lock lock = new ReentrantLock();

5/9
public void increment() {
lock.lock();
try {
count++;
} finally {
lock.unlock();
}
}

public int getCount() {


return count;
}
}

5. Deadlock in Java
A deadlock occurs when two threads hold locks on different resources and wait indefinitely
for each other.

Example: Deadlock Scenario


java

class DeadlockExample {
static final Object resource1 = new Object();
static final Object resource2 = new Object();

public static void main(String[] args) {


Thread t1 = new Thread(() -> {
synchronized (resource1) {
System.out.println("Thread 1 locked resource 1");
try { Thread.sleep(100); } catch (InterruptedException e) {}
synchronized (resource2) {
System.out.println("Thread 1 locked resource 2");
}
}
});

Thread t2 = new Thread(() -> {

6/9
synchronized (resource2) {
System.out.println("Thread 2 locked resource 2");
try { Thread.sleep(100); } catch (InterruptedException e) {}
synchronized (resource1) {
System.out.println("Thread 2 locked resource 1");
}
}
});

t1.start();
t2.start();
}
}

🛡 Output: May result in a deadlock, where both threads wait forever.

6. Thread Communication ( wait() , notify() ,


notifyAll() )

✔ Used to make threads communicate while sharing resources.

Example: Producer-Consumer Problem

java

class SharedResource {
private int data;
private boolean available = false;

public synchronized void produce(int value) {


while (available) {
try { wait(); } catch (InterruptedException e) {}
}
data = value;
available = true;
System.out.println("Produced: " + value);
notify();
}

7/9
public synchronized void consume() {
while (!available) {
try { wait(); } catch (InterruptedException e) {}
}
System.out.println("Consumed: " + data);
available = false;
notify();
}
}

public class ProducerConsumerExample {


public static void main(String[] args) {
SharedResource resource = new SharedResource();

Thread producer = new Thread(() -> {


for (int i = 1; i <= 5; i++) {
resource.produce(i);
}
});

Thread consumer = new Thread(() -> {


for (int i = 1; i <= 5; i++) {
resource.consume();
}
});

producer.start();
consumer.start();
}
}

🛡 Output (Randomized Order):

makefile

Produced: 1
Consumed: 1
Produced: 2
Consumed: 2
...

8/9
Summary
Concept Description

Thread Lifecycle States a thread goes through (New → Runnable → Running →


Terminated).

Creating Threads Thread class or Runnable interface (Runnable preferred).

Synchronization synchronized keyword or ReentrantLock to prevent data inconsistency.

Deadlock Occurs when two threads wait indefinitely for each other’s lock.

Thread Uses wait() , notify() , notifyAll() for coordination.


Communication

Next Topic: Do you want to explore Java Collections


Framework? 🚀

9/9
Core Java Best Practices

Java File Handling (Java I/O) - In-depth


Explanation
Java provides the java.io package to handle file operations such as reading, writing, and
managing files. Let’s go step by step.

1. File Handling in Java


Java provides several classes to perform file operations:

Class Purpose

File Represents file and directory pathnames.

FileReader Reads character data from a file.

FileWriter Writes character data to a file.

BufferedReader Reads text from a file efficiently.

BufferedWriter Writes text to a file efficiently.

ObjectOutputStream Used for serialization (saving objects to a file).

ObjectInputStream Used for deserialization (reading objects from a file).

2. Creating a File in Java


Use the File class to create a file.

java

import java.io.File;
import java.io.IOException;

1/8
public class CreateFileExample {
public static void main(String[] args) {
try {
File file = new File("example.txt");
if (file.createNewFile()) {
System.out.println("File created: " + file.getName());
} else {
System.out.println("File already exists.");
}
} catch (IOException e) {
System.out.println("An error occurred.");
e.printStackTrace();
}
}
}

🛡 Output:

arduino

File created: example.txt

3. Writing to a File
3.1 Using FileWriter
FileWriter is used to write character data to a file.

java

import java.io.FileWriter;
import java.io.IOException;

public class FileWriteExample {


public static void main(String[] args) {
try {
FileWriter writer = new FileWriter("example.txt");
writer.write("Hello, Java File Handling!");
writer.close();

2/8
System.out.println("Successfully written to the file.");
} catch (IOException e) {
e.printStackTrace();
}
}
}

🛡 Output: "Successfully written to the file."

📌 Note: The previous content is overwritten. Use FileWriter("example.txt", true) to


append data instead.

3.2 Using BufferedWriter (Efficient Writing)


BufferedWriter is more efficient because it uses a buffer to write data in chunks.

java

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

public class BufferedWriterExample {


public static void main(String[] args) {
try {
BufferedWriter writer = new BufferedWriter(new FileWriter("example.txt",
true));
writer.write("\nAppending new line using BufferedWriter.");
writer.close();
System.out.println("Data appended successfully.");
} catch (IOException e) {
e.printStackTrace();
}
}
}

🛡 Output: "Data appended successfully."


(New line added in the file.)

3/8
4. Reading from a File
4.1 Using FileReader
FileReader reads characters from a file.

java

import java.io.FileReader;
import java.io.IOException;

public class FileReaderExample {


public static void main(String[] args) {
try {
FileReader reader = new FileReader("example.txt");
int character;
while ((character = reader.read()) != -1) {
System.out.print((char) character);
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

🛡 Output: Hello, Java File Handling! Appending new line using BufferedWriter.

4.2 Using BufferedReader (Efficient Reading)


BufferedReader reads data line by line.

java

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class BufferedReaderExample {


public static void main(String[] args) {

4/8
try {
BufferedReader reader = new BufferedReader(new
FileReader("example.txt"));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

🛡 Output (Line-by-line reading):

arduino

Hello, Java File Handling!


Appending new line using BufferedWriter.

5. Deleting a File
You can delete a file using the delete() method of the File class.

java

import java.io.File;

public class DeleteFileExample {


public static void main(String[] args) {
File file = new File("example.txt");
if (file.delete()) {
System.out.println("File deleted: " + file.getName());
} else {
System.out.println("Failed to delete the file.");
}

5/8
}
}

🛡 Output: "File deleted: example.txt" (if exists)

6. Serialization & Deserialization


Serialization allows storing Java objects as binary data in a file and retrieving them later.

6.1 Serialization (Saving an Object to a File)


✔ Convert an object into a byte stream and save it.
✔ The class must implement Serializable .

java

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;

class Student implements Serializable {


private static final long serialVersionUID = 1L;
String name;
int age;

public Student(String name, int age) {


this.name = name;
this.age = age;
}
}

public class SerializationExample {


public static void main(String[] args) {
try {
Student student = new Student("John Doe", 22);
FileOutputStream fileOut = new FileOutputStream("student.ser");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(student);
out.close();

6/8
fileOut.close();
System.out.println("Object serialized successfully.");
} catch (IOException e) {
e.printStackTrace();
}
}
}

🛡 Output: "Object serialized successfully."

6.2 Deserialization (Reading an Object from a File)


✔ Convert a byte stream back into an object.

java

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

public class DeserializationExample {


public static void main(String[] args) {
try {
FileInputStream fileIn = new FileInputStream("student.ser");
ObjectInputStream in = new ObjectInputStream(fileIn);
Student student = (Student) in.readObject();
in.close();
fileIn.close();
System.out.println("Object deserialized: " + student.name + ", " +
student.age);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}

🛡 Output: "Object deserialized: John Doe, 22"

7/8
Summary
Concept Description

File Creation Use File class ( createNewFile() ).

Writing to File Use FileWriter , BufferedWriter .

Reading from File Use FileReader , BufferedReader .

Deleting File Use delete() method of File .

Serialization Convert object → byte stream using ObjectOutputStream .

Deserialization Convert byte stream → object using ObjectInputStream .

Next Topic: Would you like to explore Java Networking


(Socket Programming) or move to another Java topic? 🚀

8/8
Core Java Best Practices

Java 8 Features - In-depth Explanation


Java 8 introduced significant improvements to the language, making it more functional and
concise. Below are the key Java 8 features:

1. Functional Interfaces & Lambda Expressions


1.1 Functional Interfaces
A functional interface is an interface with only one abstract method. It can have multiple
default and static methods.

📌 Example of Functional Interface


java

@FunctionalInterface
interface MyFunctionalInterface {
void display(); // Single Abstract Method (SAM)

default void show() {


System.out.println("Default method in functional interface.");
}
}

1.2 Lambda Expressions


A lambda expression provides a simple way to implement a functional interface.

📌 Example without Lambda


java

class MyClass implements MyFunctionalInterface {


public void display() {
System.out.println("Hello from MyClass!");

1/8
}
}

public class LambdaExample {


public static void main(String[] args) {
MyFunctionalInterface obj = new MyClass();
obj.display();
}
}

📌 Example using Lambda


java

public class LambdaExample {


public static void main(String[] args) {
MyFunctionalInterface obj = () -> System.out.println("Hello from Lambda!");
obj.display();
}
}

🛡 Output:

csharp

Hello from Lambda!

✅ Advantages of Lambda Expressions:


Less code: No need for anonymous inner classes.

More readable: Directly pass behavior instead of creating separate classes.

Improves performance.

2. Stream API (java.util.stream)


The Stream API is used to process collections in a functional and parallelized way.

2.1 Creating Streams

2/8
java

import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

public class StreamExample {


public static void main(String[] args) {
// Creating a stream from a list
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
Stream<String> stream = names.stream();

// Using stream methods


stream.forEach(System.out::println);
}
}

🛡 Output:

nginx

Alice
Bob
Charlie

2.2 Stream Operations


Operation Description

filter() Filters elements based on a condition.

map() Transforms elements in the stream.

sorted() Sorts elements in ascending order.

collect() Collects results into a List, Set, or Map.

📌 Example: Filtering & Mapping


java

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class StreamOperations {

3/8
public static void main(String[] args) {
List<String> names = Arrays.asList("John", "Alice", "Bob", "Charlie");

List<String> filteredNames = names.stream()


.filter(name -> name.startsWith("A")) // Filters names starting with
"A"
.map(String::toUpperCase) // Converts to uppercase
.collect(Collectors.toList());

System.out.println(filteredNames);
}
}

🛡 Output:

csharp

[Alice]

3. Method References
Method references allow referring to methods by their names instead of writing lambda
expressions.

📌 Types of Method References:


Type Example

Static Method Reference ClassName::staticMethod

Instance Method Reference object::instanceMethod

Constructor Reference ClassName::new

📌 Example: Using Method References


java

import java.util.Arrays;
import java.util.List;

public class MethodReferenceExample {

4/8
public static void main(String[] args) {
List<String> names = Arrays.asList("John", "Alice", "Bob");

// Using method reference instead of lambda


names.forEach(System.out::println);
}
}

4. Default & Static Methods in Interfaces


4.1 Default Methods
Allows interfaces to have method implementations.

Helps in backward compatibility.

📌 Example of Default Method


java

interface MyInterface {
default void show() {
System.out.println("Default method in interface.");
}
}

class MyClass implements MyInterface { }

public class DefaultMethodExample {


public static void main(String[] args) {
MyClass obj = new MyClass();
obj.show(); // Calls the default method
}
}

🛡 Output:

sql

5/8
Default method in interface.

4.2 Static Methods


Defined in interfaces but not inherited by implementing classes.

Can be accessed using InterfaceName.methodName().

📌 Example of Static Method in Interface


java

interface MathUtil {
static int square(int x) {
return x * x;
}
}

public class StaticMethodExample {


public static void main(String[] args) {
int result = MathUtil.square(5);
System.out.println("Square of 5: " + result);
}
}

🛡 Output:

scss

Square of 5: 25

5. Optional Class (java.util.Optional)


The Optional class helps avoid NullPointerException.

📌 Example of Optional
6/8
java

import java.util.Optional;

public class OptionalExample {


public static void main(String[] args) {
Optional<String> optional = Optional.ofNullable(null);

// Using ifPresent() to execute code if value exists


optional.ifPresent(value -> System.out.println("Value: " + value));

// Using orElse() to provide a default value


System.out.println(optional.orElse("Default Value"));
}
}

🛡 Output:

rust

Default Value

Summary
Feature Description

Functional Interfaces & Lambda Allows functional-style programming with concise syntax.

Stream API Processes collections in a functional way.

Method References Shorter syntax for calling existing methods.

Default & Static Methods Adds functionality to interfaces without breaking old code.

Optional Class Handles null values safely to prevent exceptions.

Next Topic: Would you like to explore Java 9 Features or go deeper into
any Java 8 concept? 🚀
7/8
8/8
Core Java Best Practices

JDBC (Java Database Connectivity) - In-


depth Explanation
JDBC (Java Database Connectivity) is an API in Java that allows applications to interact with
databases. It provides methods to connect, execute queries, and manage transactions with
relational databases like MySQL, PostgreSQL, Oracle, etc.

1. Steps to Connect Java with a Database


To connect Java with a database using JDBC, follow these steps:

Step 1: Load the JDBC Driver


Each database has a specific JDBC driver that must be loaded before connecting.

java

Class.forName("com.mysql.cj.jdbc.Driver"); // MySQL Driver

Note: Since JDBC 4.0, the driver is auto-loaded when DriverManager.getConnection() is


called.

Step 2: Establish a Connection


Create a connection using DriverManager.getConnection() .

java

Connection con = DriverManager.getConnection(


"jdbc:mysql://localhost:3306/mydatabase", "username", "password");

1/5
URL format: jdbc:mysql://hostname:port/databaseName

Example for different databases:

MySQL: "jdbc:mysql://localhost:3306/mydb"

PostgreSQL: "jdbc:postgresql://localhost:5432/mydb"

Oracle: "jdbc:oracle:thin:@localhost:1521:xe"

Step 3: Create a Statement


There are three types of statements in JDBC:

Statement Type Description

Statement Used for static queries.

PreparedStatement Used for parameterized queries (prevents SQL injection).

CallableStatement Used to call stored procedures.

Example:

java

Statement stmt = con.createStatement();

Step 4: Execute the Query


For SELECT queries, use executeQuery() .

For INSERT, UPDATE, DELETE, use executeUpdate() .

java

ResultSet rs = stmt.executeQuery("SELECT * FROM users");


while (rs.next()) {
System.out.println(rs.getString("username"));
}

2/5
Step 5: Close the Connection
Always close the connection to free up resources.

java

con.close();

2. JDBC Drivers
JDBC drivers enable Java applications to interact with different databases.

JDBC Driver Type Description

Type 1: JDBC-ODBC Bridge Uses ODBC driver; not recommended.

Type 2: Native-API Driver Uses database-specific native API; requires client installation.

Type 3: Network Protocol Driver Uses middleware to communicate with databases.

Type 4: Thin Driver (Pure Java) Directly connects to the database; most commonly used.

✅ Example JDBC Drivers:


MySQL: com.mysql.cj.jdbc.Driver

PostgreSQL: org.postgresql.Driver

Oracle: oracle.jdbc.driver.OracleDriver

3. CRUD Operations with JDBC


3.1 Create (INSERT)

java

Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb",


"root", "password");

3/5
String sql = "INSERT INTO users (name, email) VALUES (?, ?)";
PreparedStatement pstmt = con.prepareStatement(sql);
pstmt.setString(1, "John Doe");
pstmt.setString(2, "john@example.com");

int rowsInserted = pstmt.executeUpdate();


System.out.println(rowsInserted + " row(s) inserted.");

con.close();

3.2 Read (SELECT)

java

String sql = "SELECT * FROM users";


Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(sql);

while (rs.next()) {
System.out.println("User: " + rs.getString("name") + ", Email: " +
rs.getString("email"));
}

3.3 Update

java

String sql = "UPDATE users SET email = ? WHERE name = ?";


PreparedStatement pstmt = con.prepareStatement(sql);
pstmt.setString(1, "newemail@example.com");
pstmt.setString(2, "John Doe");

int rowsUpdated = pstmt.executeUpdate();


System.out.println(rowsUpdated + " row(s) updated.");

4/5
3.4 Delete

java

String sql = "DELETE FROM users WHERE name = ?";


PreparedStatement pstmt = con.prepareStatement(sql);
pstmt.setString(1, "John Doe");

int rowsDeleted = pstmt.executeUpdate();


System.out.println(rowsDeleted + " row(s) deleted.");

Conclusion
JDBC provides a standard way to interact with databases. Key points:

Steps to connect: Load driver → Establish connection → Create statement → Execute


query → Close connection.

JDBC drivers: Type 1-4; Type 4 is the most common.

CRUD operations: executeQuery() for reading, executeUpdate() for insert, update,


and delete.

Next Topic: Do you want to explore JDBC Transactions (commit &


rollback) or any specific database integration? 🚀

5/5
Core Java Best Practices

Design Patterns - Basic Understanding


Design patterns are best practices used in software development to solve common problems
efficiently. They improve code reusability, scalability, and maintainability.

1. Singleton Pattern
Definition
The Singleton Pattern ensures that a class has only one instance and provides a global
access point to it.

Use Cases
Managing database connections.

Logging frameworks.

Configuration settings.

Implementation
java

class Singleton {
private static Singleton instance;

private Singleton() { } // Private constructor

public static Singleton getInstance() {


if (instance == null) {
instance = new Singleton();
}
return instance;
}
}

1/8
public class SingletonExample {
public static void main(String[] args) {
Singleton obj1 = Singleton.getInstance();
Singleton obj2 = Singleton.getInstance();

System.out.println(obj1 == obj2); // Output: true (same instance)


}
}

Thread-Safe Singleton

java

class Singleton {
private static Singleton instance;

private Singleton() { }

public static synchronized Singleton getInstance() {


if (instance == null) {
instance = new Singleton();
}
return instance;
}
}

✅ Advantages:
Saves memory by preventing multiple instances.

Centralized control.

🚫 Disadvantages:
Can be difficult to unit test due to global state.

2. Factory Pattern
Definition

2/8
The Factory Pattern provides an interface for creating objects but lets subclasses decide the
instantiation.

Use Cases
When object creation logic is complex.

When you need to create multiple related objects without exposing the instantiation
logic.

Implementation

java

// Step 1: Create an interface


interface Shape {
void draw();
}

// Step 2: Implement different classes


class Circle implements Shape {
public void draw() {
System.out.println("Drawing a Circle");
}
}

class Square implements Shape {


public void draw() {
System.out.println("Drawing a Square");
}
}

// Step 3: Create a Factory class


class ShapeFactory {
public static Shape getShape(String shapeType) {
if (shapeType.equalsIgnoreCase("CIRCLE")) {
return new Circle();
} else if (shapeType.equalsIgnoreCase("SQUARE")) {
return new Square();
}
return null;
}
}

3/8
// Step 4: Use the Factory
public class FactoryExample {
public static void main(String[] args) {
Shape shape1 = ShapeFactory.getShape("CIRCLE");
shape1.draw(); // Output: Drawing a Circle

Shape shape2 = ShapeFactory.getShape("SQUARE");


shape2.draw(); // Output: Drawing a Square
}
}

✅ Advantages:
Promotes loose coupling.

Centralized object creation.

🚫 Disadvantages:
Additional class overhead.

3. Builder Pattern
Definition
The Builder Pattern simplifies object creation when a class has many optional parameters.

Use Cases
When a class has too many constructor parameters.

When an object needs to be immutable.

Implementation

java

class Car {
private String engine;
private int wheels;
private boolean sunroof;

4/8
private Car(CarBuilder builder) {
this.engine = builder.engine;
this.wheels = builder.wheels;
this.sunroof = builder.sunroof;
}

public static class CarBuilder {


private String engine;
private int wheels;
private boolean sunroof;

public CarBuilder(String engine, int wheels) {


this.engine = engine;
this.wheels = wheels;
}

public CarBuilder setSunroof(boolean sunroof) {


this.sunroof = sunroof;
return this;
}

public Car build() {


return new Car(this);
}
}

@Override
public String toString() {
return "Car [engine=" + engine + ", wheels=" + wheels + ", sunroof=" +
sunroof + "]";
}
}

public class BuilderExample {


public static void main(String[] args) {
Car car = new Car.CarBuilder("V8", 4)
.setSunroof(true)
.build();

System.out.println(car); // Output: Car [engine=V8, wheels=4, sunroof=true]

5/8
}
}

✅ Advantages:
Improves readability for large constructors.

Ensures immutability.

🚫 Disadvantages:
Slightly more code than using multiple constructors.

4. Observer Pattern
Definition
The Observer Pattern defines a one-to-many dependency, meaning when one object
changes state, all its dependents (observers) are notified.

Use Cases
Event-driven programming (e.g., GUI applications).

Real-time notifications.

Implementation
java

import java.util.ArrayList;
import java.util.List;

// Step 1: Create an Observer interface


interface Observer {
void update(String message);
}

// Step 2: Create a Subject (Observable)


class NewsAgency {
private List<Observer> observers = new ArrayList<>();

6/8
public void addObserver(Observer observer) {
observers.add(observer);
}

public void notifyObservers(String news) {


for (Observer observer : observers) {
observer.update(news);
}
}
}

// Step 3: Create Concrete Observers


class Subscriber implements Observer {
private String name;

public Subscriber(String name) {


this.name = name;
}

public void update(String message) {


System.out.println(name + " received update: " + message);
}
}

// Step 4: Use the Observer pattern


public class ObserverExample {
public static void main(String[] args) {
NewsAgency newsAgency = new NewsAgency();

Observer subscriber1 = new Subscriber("Alice");


Observer subscriber2 = new Subscriber("Bob");

newsAgency.addObserver(subscriber1);
newsAgency.addObserver(subscriber2);

newsAgency.notifyObservers("Breaking News: Observer Pattern Implemented!");


}
}

🛡 Output:

sql

7/8
Alice received update: Breaking News: Observer Pattern Implemented!
Bob received update: Breaking News: Observer Pattern Implemented!

✅ Advantages:
Decouples subjects and observers, making systems flexible.

Useful in event-driven architectures.

🚫 Disadvantages:
Can cause memory leaks if observers are not removed when no longer needed.

Summary
Pattern Description Use Case

Singleton Ensures only one instance of a Logging, Configuration, Database connections.


class.

Factory Centralized object creation. When multiple similar objects are created
dynamically.

Builder Simplifies complex object Objects with many optional parameters (Immutable
creation. objects).

Observer Allows objects to listen for Event-driven systems, notifications.


updates.

Next Topic: Would you like to explore more Design Patterns (e.g.,
Prototype, Adapter, Strategy) or go deeper into one of the above? 🚀

8/8
Core Java Best Practices

Memory Management & Garbage


Collection in Java
Memory management in Java is handled by the JVM (Java Virtual Machine), which
automatically allocates and deallocates memory. The Garbage Collector (GC) is responsible
for cleaning up unused objects.

1. Stack vs Heap Memory


Java divides memory into two main areas: Stack and Heap.

📝 Stack Memory (Method Execution)


Stores method calls, local variables, and references to objects.

Follows LIFO (Last In, First Out).

Memory is automatically allocated and deallocated when a method is called or returns.

🔹 Example of Stack Memory:


java

class StackExample {
void methodA() {
int x = 10; // Stored in Stack
methodB();
}

void methodB() {
int y = 20; // Stored in Stack
}

public static void main(String[] args) {


StackExample obj = new StackExample(); // Reference stored in Stack, Object

1/6
stored in Heap
obj.methodA();
}
}

📝 Heap Memory (Object Storage)


Stores objects and class instances.

Objects are created using new keyword.

JVM’s Garbage Collector (GC) manages memory deallocation.

🔹 Example of Heap Memory:


java

class HeapExample {
int data; // Instance variable stored in Heap

HeapExample(int data) {
this.data = data;
}

public static void main(String[] args) {


HeapExample obj1 = new HeapExample(100); // Stored in Heap
HeapExample obj2 = new HeapExample(200); // Stored in Heap
}
}

📌 Key Differences Between Stack and Heap:


Feature Stack Heap

Storage Method calls, local variables Objects, instance variables

Access Fast Slower

Lifetime Short (Method execution) Long (Until GC removes it)

Management Managed by JVM automatically Managed by Garbage Collector

2. Garbage Collection Mechanisms in Java

2/6
The Garbage Collector (GC) removes unused objects from the Heap to free up memory.

Garbage Collection Process


1. Mark – Identifies which objects are in use.

2. Sweep – Deletes unreferenced objects.

3. Compact – Rearranges remaining objects to improve memory allocation.

Types of Garbage Collectors


Java provides multiple GC algorithms:

GC Type Description

Serial GC Single-threaded, best for small applications.

Parallel GC Uses multiple threads for GC. Default for JVM before Java 9.

G1 (Garbage First) GC Low-latency GC, default from Java 9 onwards.

ZGC (Experimental) Ultra-low latency, handles large heaps efficiently.

🔹 Forcing Garbage Collection Manually


java

System.gc(); // Requests GC (Not guaranteed)

3. Weak References & Soft References


Java provides different types of references to manage memory efficiently.

🔹 Strong Reference (Default)


Prevents garbage collection as long as a reference exists.

Example:

java

String str = new String("Hello"); // Strong reference

3/6
🔹 Soft Reference (GC removes if memory is low)
Used for caching.

Example:

java

import java.lang.ref.SoftReference;

public class SoftRefExample {


public static void main(String[] args) {
String data = new String("Cache Data");
SoftReference<String> softRef = new SoftReference<>(data);

data = null; // Eligible for GC if memory is low


System.out.println(softRef.get()); // Still accessible
}
}

🔹 Weak Reference (GC removes in next cycle)


Used for memory-sensitive objects like WeakHashMap.

Example:

java

import java.lang.ref.WeakReference;

public class WeakRefExample {


public static void main(String[] args) {
String data = new String("Temporary Data");
WeakReference<String> weakRef = new WeakReference<>(data);

data = null; // Now weakly reachable


System.gc(); // Requests GC
System.out.println(weakRef.get()); // May return null
}
}

🔹 Phantom Reference (Used for finalization)


4/6
Used when the object is almost ready for GC.

Example:

java

import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;

public class PhantomRefExample {


public static void main(String[] args) {
String data = new String("Phantom Data");
ReferenceQueue<String> queue = new ReferenceQueue<>();
PhantomReference<String> phantomRef = new PhantomReference<>(data, queue);

data = null;
System.gc();
System.out.println(phantomRef.get()); // Always null
}
}

📌 Comparison of References:
Type When is it Collected? Example Use Case

Strong Never (unless set to null ) Regular object references

Soft If memory is low Caching, Image loading

Weak In next GC cycle WeakHashMap

Phantom Before object is finalized Resource cleanup

Summary
Stack stores method calls & local variables, while Heap stores objects.

Garbage Collector (GC) automatically removes unused objects.

Use Soft/Weak References for memory optimization.

Choose the right GC Algorithm based on application needs.

5/6
Would you like more details on GC tuning or JVM memory monitoring tools? 🚀

6/6
Core Java Best Practices

Reflection API & Annotations in Java


1. Reflection API
The Reflection API in Java allows inspection and manipulation of classes, methods, fields,
and constructors at runtime.

📌 Key Features of Reflection API


Inspect class details (methods, fields, constructors).

Modify private fields and invoke private methods.

Create objects dynamically.

🔹 Example: Getting Class Information


java

import java.lang.reflect.Method;
import java.lang.reflect.Field;
import java.lang.reflect.Constructor;

class Example {
private String name;

public Example() {}

public void show() {


System.out.println("Hello, Reflection API!");
}
}

public class ReflectionDemo {


public static void main(String[] args) {
Class<?> obj = Example.class;

// Get Class Name


System.out.println("Class Name: " + obj.getName());

1/7
// Get Methods
Method[] methods = obj.getDeclaredMethods();
for (Method method : methods) {
System.out.println("Method: " + method.getName());
}

// Get Fields
Field[] fields = obj.getDeclaredFields();
for (Field field : fields) {
System.out.println("Field: " + field.getName());
}

// Get Constructors
Constructor<?>[] constructors = obj.getDeclaredConstructors();
for (Constructor<?> constructor : constructors) {
System.out.println("Constructor: " + constructor.getName());
}
}
}

🔹 Modifying Private Fields Using Reflection


java

import java.lang.reflect.Field;

class Student {
private String name = "John";

public void display() {


System.out.println("Name: " + name);
}
}

public class ModifyPrivateField {


public static void main(String[] args) throws Exception {
Student student = new Student();
student.display();

// Access private field


Field field = Student.class.getDeclaredField("name");

2/7
field.setAccessible(true);
field.set(student, "Alice");

student.display();
}
}

🚀 Use Cases of Reflection API


Frameworks (Spring, Hibernate) use Reflection for dependency injection.

Testing (JUnit, Mockito) uses Reflection to invoke private methods.

Serialization/Deserialization libraries (Jackson, Gson).

2. Java Annotations
Annotations provide metadata about classes, methods, or fields.

🔹 Common Built-in Annotations


Annotation Description

@Override Ensures a method is overriding a superclass method.

@FunctionalInterface Ensures an interface has only one abstract method.

@SuppressWarnings Suppresses compiler warnings.

@Deprecated Marks a method/class as deprecated.

🔹 @Override Example
java

class Parent {
void display() {
System.out.println("Parent class");
}
}

class Child extends Parent {


@Override

3/7
void display() { // Ensures this method is actually overriding the parent method
System.out.println("Child class");
}
}

🔹 @FunctionalInterface Example
java

@FunctionalInterface
interface MyFunctionalInterface {
void greet();
}

public class FunctionalDemo {


public static void main(String[] args) {
MyFunctionalInterface obj = () -> System.out.println("Hello, Lambda!");
obj.greet();
}
}

🔹 @SuppressWarnings Example
java

public class SuppressWarningDemo {


@SuppressWarnings("deprecation")
public static void main(String[] args) {
OldClass obj = new OldClass();
obj.display();
}
}

class OldClass {
@Deprecated
void display() {
System.out.println("This method is deprecated");
}
}

🔹 @Deprecated Example
4/7
java

class OldVersion {
@Deprecated
public void oldMethod() {
System.out.println("This method is outdated.");
}
}

public class DeprecatedDemo {


public static void main(String[] args) {
OldVersion obj = new OldVersion();
obj.oldMethod(); // Warning: Deprecated method
}
}

3. Creating Custom Annotations


We can define our own annotations using @interface .

🔹 Steps to Create a Custom Annotation


1. Define the annotation using @interface .

2. Use @Retention to specify if it's available at runtime.

3. Use @Target to specify where it can be used (Class, Method, Field, etc.).

4. Apply the annotation to a method or class.

5. Use Reflection to process the annotation.

🔹 Example: Creating & Using Custom Annotations


java

import java.lang.annotation.*;
import java.lang.reflect.*;

@Retention(RetentionPolicy.RUNTIME) // Available at runtime


@Target(ElementType.METHOD) // Can be applied to methods

5/7
@interface MyAnnotation {
String value();
}

class CustomAnnotationExample {
@MyAnnotation(value = "Hello Annotation")
public void testMethod() {
System.out.println("Method Executed");
}
}

public class CustomAnnotationDemo {


public static void main(String[] args) throws Exception {
CustomAnnotationExample obj = new CustomAnnotationExample();
Method method = obj.getClass().getMethod("testMethod");

if (method.isAnnotationPresent(MyAnnotation.class)) {
MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
System.out.println("Annotation Value: " + annotation.value());
}

obj.testMethod();
}
}

📌 Explanation:
@Retention(RetentionPolicy.RUNTIME) : Annotation is available at runtime.

@Target(ElementType.METHOD) : Can be applied only to methods.

Reflection API reads the annotation at runtime.

Summary
Reflection API allows dynamic class inspection and modification.

Annotations provide metadata for classes, methods, and variables.

Custom Annotations can be created for specific use cases.

6/7
Frameworks like Spring, Hibernate, and JUnit rely heavily on Reflection and
Annotations.

Would you like more details on Spring Boot annotations? 🚀

7/7
Core Java Best Practices

Inner Classes in Java


Inner classes in Java are classes defined within another class. They help group logically
related classes together, improve encapsulation, and enhance code readability.

1. Regular Inner Class (Member Inner Class)


A regular inner class is a non-static class defined inside another class. It has access to all
members of the outer class, including private members.

📌 Key Points
Requires an instance of the outer class to be instantiated.

Can access private members of the outer class.

🔹 Example: Regular Inner Class


java

class OuterClass {
private String message = "Hello from Outer Class";

// Inner Class
class InnerClass {
void display() {
System.out.println(message); // Accessing outer class private member
}
}
}

public class RegularInnerClassDemo {


public static void main(String[] args) {
OuterClass outer = new OuterClass();
OuterClass.InnerClass inner = outer.new InnerClass(); // Creating inner
class object
inner.display();

1/6
}
}

📌 Explanation:
InnerClass is a non-static member of OuterClass .

InnerClass can access the private message variable.

2. Static Nested Class


A static nested class is a static class inside another class. Unlike regular inner classes, it does
not require an instance of the outer class.

📌 Key Points
Can only access static members of the outer class.

Instantiated without an instance of the outer class.

🔹 Example: Static Nested Class


java

class OuterClass {
static String message = "Hello from Outer Class";

// Static Nested Class


static class StaticNestedClass {
void display() {
System.out.println(message); // Can access only static members
}
}
}

public class StaticNestedClassDemo {


public static void main(String[] args) {
OuterClass.StaticNestedClass nested = new OuterClass.StaticNestedClass(); //
No need for an OuterClass instance
nested.display();

2/6
}
}

📌 Explanation:
StaticNestedClass is declared with static , so it does not require an instance of

OuterClass .

It can only access static variables/methods from OuterClass .

3. Anonymous Inner Class


An anonymous inner class is a class without a name, created for one-time use. It is mainly
used with interfaces or abstract classes.

📌 Key Points
Defined and instantiated in a single expression.

Can be used to override methods of an interface or a superclass.

🔹 Example: Anonymous Inner Class using an Interface


java

interface Greeting {
void sayHello();
}

public class AnonymousInnerClassDemo {


public static void main(String[] args) {
Greeting greet = new Greeting() {
public void sayHello() {
System.out.println("Hello from Anonymous Inner Class!");
}
};
greet.sayHello();
}
}

📌 Explanation:
3/6
We created an anonymous inner class that implements the Greeting interface without
a separate class declaration.

🔹 Example: Anonymous Inner Class using a Class


java

abstract class Animal {


abstract void makeSound();
}

public class AnonymousClassExample {


public static void main(String[] args) {
Animal cat = new Animal() {
void makeSound() {
System.out.println("Meow! Meow!");
}
};
cat.makeSound();
}
}

📌 Explanation:
We created an anonymous inner class that extends Animal and overrides
makeSound() .

4. Local Inner Class


A local inner class is a class declared inside a method. It is accessible only within that
method.

📌 Key Points
Defined inside a method and cannot be accessed outside.

Can access local variables of the method if they are final or effectively final.

🔹 Example: Local Inner Class

4/6
java

class OuterClass {
void outerMethod() {
System.out.println("Inside Outer Method");

class LocalInnerClass {
void localDisplay() {
System.out.println("Inside Local Inner Class");
}
}

LocalInnerClass localInner = new LocalInnerClass();


localInner.localDisplay();
}
}

public class LocalInnerClassDemo {


public static void main(String[] args) {
OuterClass outer = new OuterClass();
outer.outerMethod();
}
}

📌 Explanation:
LocalInnerClass is defined inside outerMethod() , so it cannot be used outside the
method.

Local inner classes can access variables from the enclosing method if they are final or
effectively final.

Summary
Requires Outer Class Access to Outer Class
Inner Class Type Static? Instance? Members

Regular Inner Class ❌ No ✅ Yes ✅ Yes (All Members)


Static Nested Class ✅ Yes ❌ No ❌ Only Static Members

5/6
Requires Outer Class Access to Outer Class
Inner Class Type Static? Instance? Members

Anonymous Inner ❌ No ✅ Yes ✅ Yes (All Members)


Class

Local Inner Class ❌ No ✅ Yes ✅ Yes (Final Variables Only)

Real-World Use Cases


✅ Regular Inner Class: Encapsulating helper classes that need access to private members.
✅ Static Nested Class: Utility classes like
Map.Entry in Java collections.
✅ Anonymous Inner Class: Event handling in GUI applications.
✅ Local Inner Class: Encapsulating logic within a method.
Would you like more examples on any specific type of inner class? 🚀

6/6
Core Java Best Practices

Java Networking
Java Networking allows communication between computers using TCP/IP protocols. Java
provides built-in classes in the java.net package to handle networking.

1. Sockets & HTTP Communication


📌 What is a Socket?
A socket is an endpoint for sending or receiving data across a network. Java supports two
types of sockets:

1. TCP Sockets (Reliable, Connection-Oriented)

2. UDP Sockets (Faster, Connectionless)

🔹 TCP Socket Programming


TCP (Transmission Control Protocol) ensures reliable data transfer.

🔸 Server Side (Socket Server)


java

import java.io.*;
import java.net.*;

public class TCPServer {


public static void main(String[] args) {
try (ServerSocket serverSocket = new ServerSocket(5000)) {
System.out.println("Server is waiting for a client...");

Socket socket = serverSocket.accept();


System.out.println("Client connected!");

BufferedReader input = new BufferedReader(new

1/7
InputStreamReader(socket.getInputStream()));
PrintWriter output = new PrintWriter(socket.getOutputStream(), true);

String clientMessage = input.readLine();


System.out.println("Client says: " + clientMessage);

output.println("Hello from Server!");

socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

🔸 Client Side (Socket Client)


java

import java.io.*;
import java.net.*;

public class TCPClient {


public static void main(String[] args) {
try (Socket socket = new Socket("localhost", 5000)) {
BufferedReader input = new BufferedReader(new
InputStreamReader(socket.getInputStream()));
PrintWriter output = new PrintWriter(socket.getOutputStream(), true);

output.println("Hello from Client!");

String serverMessage = input.readLine();


System.out.println("Server says: " + serverMessage);
} catch (IOException e) {
e.printStackTrace();
}
}
}

📌 Explanation:
ServerSocket listens on port 5000.

2/7
Socket connects the client to the server.

BufferedReader & PrintWriter handle data transmission.

🔹 UDP Socket Programming


UDP (User Datagram Protocol) is faster but unreliable.

🔸 UDP Server
java

import java.net.*;

public class UDPServer {


public static void main(String[] args) {
try (DatagramSocket socket = new DatagramSocket(5000)) {
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);

System.out.println("Server is waiting for a message...");


socket.receive(packet);

String received = new String(packet.getData(), 0, packet.getLength());


System.out.println("Client says: " + received);
} catch (Exception e) {
e.printStackTrace();
}
}
}

🔸 UDP Client
java

import java.net.*;

public class UDPClient {


public static void main(String[] args) {
try (DatagramSocket socket = new DatagramSocket()) {
String message = "Hello UDP Server!";

3/7
byte[] buffer = message.getBytes();
InetAddress address = InetAddress.getByName("localhost");

DatagramPacket packet = new DatagramPacket(buffer, buffer.length,


address, 5000);
socket.send(packet);
System.out.println("Message sent to server!");
} catch (Exception e) {
e.printStackTrace();
}
}
}

📌 Key Differences Between TCP & UDP


Feature TCP (Sockets) UDP (DatagramSockets)

Connection Connection-oriented Connectionless

Reliability Reliable Unreliable

Speed Slower Faster

Usage File transfer, web browsing VoIP, streaming

2. URL & URLConnection


Java provides the java.net.URL and URLConnection classes to interact with URLs.

🔹 Fetching Webpage Content


java

import java.io.*;
import java.net.*;

public class URLReader {


public static void main(String[] args) {
try {
URL url = new URL("https://www.example.com");
BufferedReader reader = new BufferedReader(new
InputStreamReader(url.openStream()));

4/7
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}

📌 Explanation:
URL.openStream() opens a stream to the webpage.

BufferedReader reads the webpage content line by line.

🔹 Sending an HTTP GET Request


java

import java.io.*;
import java.net.*;

public class HTTPGetRequest {


public static void main(String[] args) {
try {
URL url = new URL("https://jsonplaceholder.typicode.com/posts/1");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");

BufferedReader reader = new BufferedReader(new


InputStreamReader(connection.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
reader.close();
} catch (Exception e) {

5/7
e.printStackTrace();
}
}
}

📌 Explanation:
HttpURLConnection is used to send GET requests.

getInputStream() reads the response.

🔹 Sending an HTTP POST Request


java

import java.io.*;
import java.net.*;

public class HTTPPostRequest {


public static void main(String[] args) {
try {
URL url = new URL("https://jsonplaceholder.typicode.com/posts");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json");
connection.setDoOutput(true);

String jsonData = "{\"title\": \"foo\", \"body\": \"bar\", \"userId\":


1}";
OutputStream os = connection.getOutputStream();
os.write(jsonData.getBytes());
os.flush();
os.close();

BufferedReader reader = new BufferedReader(new


InputStreamReader(connection.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}

6/7
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}

📌 Explanation:
setRequestMethod("POST") sets the request type.

setDoOutput(true) allows writing data.

JSON data is sent using OutputStream .

Summary
Feature Key Classes

Sockets (TCP/UDP) Socket , ServerSocket , DatagramSocket , DatagramPacket

HTTP Communication HttpURLConnection

URL Handling URL , URLConnection

Real-World Use Cases


✅ Sockets (TCP/UDP) – Chat applications, multiplayer games
✅ URL & URLConnection – Web scraping, API calls
✅ HTTP Communication – REST API integration
Would you like additional details on any of these topics? 🚀

7/7
Core Java Best Practices

Java Security
Java provides various security mechanisms to protect data through Hashing, Encryption,
and Decryption techniques. These are essential for securing passwords, sensitive data, and
communication.

1. Hashing (MD5, SHA)


Hashing is a one-way function that converts data into a fixed-length value, making it
impossible to reverse. It's commonly used for password storage.

🔹 MD5 (Message Digest Algorithm 5)


MD5 produces a 128-bit hash value (32 hexadecimal characters). However, it is considered
insecure due to collision vulnerabilities.

Example: Hashing a String Using MD5

java

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MD5Hashing {


public static String hashMD5(String input) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] messageDigest = md.digest(input.getBytes());
StringBuilder hexString = new StringBuilder();

for (byte b : messageDigest) {


hexString.append(String.format("%02x", b));
}

return hexString.toString();

1/6
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}

public static void main(String[] args) {


System.out.println("MD5 Hash: " + hashMD5("HelloWorld"));
}
}

📌 Output Example:
yaml

MD5 Hash: fc5e038d38a57032085441e7fe7010b0

🛑 Weakness: MD5 is vulnerable to hash collisions, where two different inputs produce the
same hash.

🔹 SHA (Secure Hash Algorithm)


SHA produces a more secure hash compared to MD5. Java supports multiple versions:

SHA-1: 160-bit hash (deprecated due to weaknesses)

SHA-256: 256-bit hash (more secure)

SHA-512: 512-bit hash (stronger security)

Example: Hashing a String Using SHA-256

java

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class SHAHashing {


public static String hashSHA256(String input) {
try {
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] messageDigest = md.digest(input.getBytes());

2/6
StringBuilder hexString = new StringBuilder();

for (byte b : messageDigest) {


hexString.append(String.format("%02x", b));
}

return hexString.toString();
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}

public static void main(String[] args) {


System.out.println("SHA-256 Hash: " + hashSHA256("HelloWorld"));
}
}

📌 Output Example:
yaml

SHA-256 Hash: a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b53a4d6b6ddf0f4d5

✅ SHA-256 is widely used for password hashing, digital signatures, and data integrity.

2. Encryption & Decryption (AES, RSA)


Encryption converts plaintext into ciphertext, and decryption reverts it back to plaintext.

🔹 AES (Advanced Encryption Standard)


AES is a symmetric-key encryption algorithm (same key is used for encryption and
decryption). It supports 128-bit, 192-bit, and 256-bit key sizes.

Example: AES Encryption & Decryption

java

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;

3/6
import javax.crypto.SecretKey;
import java.util.Base64;

public class AESEncryption {


public static void main(String[] args) throws Exception {
String data = "HelloAES";

// Generate AES Key


KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(128); // 128-bit AES
SecretKey secretKey = keyGen.generateKey();

// Encrypt Data
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] encryptedData = cipher.doFinal(data.getBytes());
String encryptedText = Base64.getEncoder().encodeToString(encryptedData);
System.out.println("Encrypted: " + encryptedText);

// Decrypt Data
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] decryptedData =
cipher.doFinal(Base64.getDecoder().decode(encryptedText));
System.out.println("Decrypted: " + new String(decryptedData));
}
}

📌 Output Example:
pgsql

Encrypted: s9BbxHTH8T6UYWd/KT8vxQ==
Decrypted: HelloAES

✅ AES is widely used in file encryption, database encryption, and secure communication.

🔹 RSA (Rivest-Shamir-Adleman)
RSA is an asymmetric encryption algorithm, meaning it uses:

4/6
Public Key (for encryption)

Private Key (for decryption)

Example: RSA Encryption & Decryption

java

import java.security.*;
import javax.crypto.Cipher;
import java.util.Base64;

public class RSAEncryption {


public static void main(String[] args) throws Exception {
String data = "HelloRSA";

// Generate Key Pair


KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(2048);
KeyPair keyPair = keyGen.generateKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();

// Encrypt Data
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encryptedData = cipher.doFinal(data.getBytes());
String encryptedText = Base64.getEncoder().encodeToString(encryptedData);
System.out.println("Encrypted: " + encryptedText);

// Decrypt Data
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decryptedData =
cipher.doFinal(Base64.getDecoder().decode(encryptedText));
System.out.println("Decrypted: " + new String(decryptedData));
}
}

📌 Output Example:
makefile

Encrypted: ZmVmM3NydDg...

5/6
Decrypted: HelloRSA

✅ RSA is commonly used in SSL/TLS certificates, digital signatures, and secure email
communication.

🔹 Key Differences Between AES & RSA


Feature AES RSA

Type Symmetric Asymmetric

Key Used Single Secret Key Public & Private Key

Speed Fast Slower

Usage Data encryption Secure communication, digital signatures

Summary
Security Feature Algorithm Use Case

Hashing MD5, SHA-256 Password hashing, data integrity

Encryption AES File encryption, database encryption

Asymmetric Encryption RSA Digital signatures, secure key exchange

Real-World Use Cases


🔹 Hashing: Secure password storage in databases
🔹 AES Encryption: Encrypting sensitive files
🔹 RSA Encryption: Secure web communication (SSL/TLS)
Would you like a more detailed explanation or a different example? 🚀

6/6
Core Java Best Practices

I'll provide an in-depth explanation of each Java interview-specific topic, starting with key
differences and then covering common coding questions.

1. Differences Between Important Java Concepts


🔹 == vs .equals()

Feature == Operator .equals() Method

Type Compares memory addresses Compares content (for objects)

Use Case Used for primitive types and object Used for content comparison in objects
references

Example "hello" == "hello" → true (same "hello".equals("hello") → true


(Strings) reference in String Pool)

Example new String("abc") == new new String("abc").equals(new


(Objects) String("abc") → false String("abc")) → true

Example Code

java

String s1 = new String("Java");


String s2 = new String("Java");

System.out.println(s1 == s2); // false (different memory locations)


System.out.println(s1.equals(s2)); // true (same content)

🔹 StringBuffer vs StringBuilder

Feature StringBuffer StringBuilder

Mutability Mutable Mutable

1/8
Feature StringBuffer StringBuilder

Thread-Safety Thread-safe (synchronized) Not thread-safe (faster)

Performance Slower due to synchronization Faster as it is not synchronized

Example Code

java

StringBuffer sb1 = new StringBuffer("Hello");


sb1.append(" World");
System.out.println(sb1); // Hello World

StringBuilder sb2 = new StringBuilder("Hello");


sb2.append(" World");
System.out.println(sb2); // Hello World

🔹 ArrayList vs LinkedList

Feature ArrayList LinkedList

Implementation Dynamic array Doubly linked list

Insertion/Deletion Slow (shifting required) Fast (no shifting needed)

Random Access Fast (direct index access) Slow (traverse needed)

Memory Usage Less (no extra pointers) More (extra pointers for nodes)

Example Code

java

List<Integer> arrayList = new ArrayList<>();


List<Integer> linkedList = new LinkedList<>();

🔹 HashMap vs Hashtable

2/8
Feature HashMap Hashtable

Thread-Safety Not synchronized Synchronized

Performance Faster Slower

Allows null Keys/Values? Yes No

Example Code

java

HashMap<Integer, String> hashMap = new HashMap<>();


hashMap.put(null, "Value"); // Allowed

Hashtable<Integer, String> hashtable = new Hashtable<>();


// hashtable.put(null, "Value"); // Throws NullPointerException

🔹 final vs finally vs finalize

Feature final finally finalize

Usage Keyword for constants, method Cleanup block in Garbage collection hook
overriding prevention try-catch

Example final int x = 10; try { ... } finally protected void


{ ... } finalize() { }

Example Code

java

// final keyword
final int x = 10;

// finally block
try {
System.out.println("Inside try");
} finally {
System.out.println("Inside finally");
}

// finalize method

3/8
class Test {
protected void finalize() { System.out.println("Object garbage collected"); }
}

2. Common Coding Questions


🔹 Fibonacci Series
Print Fibonacci series up to n numbers.

java

public class Fibonacci {


public static void main(String[] args) {
int n = 10, a = 0, b = 1;
System.out.print(a + " " + b);

for (int i = 2; i < n; i++) {


int next = a + b;
System.out.print(" " + next);
a = b;
b = next;
}
}
}

📌 Output:

0 1 1 2 3 5 8 13 21 34

🔹 Palindrome Check (String & Number)


java

4/8
public class Palindrome {
public static boolean isPalindrome(String str) {
return str.equals(new StringBuilder(str).reverse().toString());
}

public static boolean isPalindrome(int num) {


int rev = 0, temp = num;
while (temp > 0) {
rev = rev * 10 + temp % 10;
temp /= 10;
}
return rev == num;
}

public static void main(String[] args) {


System.out.println(isPalindrome("madam")); // true
System.out.println(isPalindrome(121)); // true
}
}

🔹 Sorting Algorithms
🔸 Bubble Sort
java

public class BubbleSort {


public static void bubbleSort(int[] arr) {
int n = arr.length;
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}

5/8
}
}

🔸 Quick Sort
java

public class QuickSort {


public static void quickSort(int[] arr, int low, int high) {
if (low < high) {
int pi = partition(arr, low, high);
quickSort(arr, low, pi - 1);
quickSort(arr, pi + 1, high);
}
}

private static int partition(int[] arr, int low, int high) {


int pivot = arr[high], i = low - 1;
for (int j = low; j < high; j++) {
if (arr[j] < pivot) {
i++;
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
int temp = arr[i + 1];
arr[i + 1] = arr[high];
arr[high] = temp;
return i + 1;
}
}

🔹 Find Duplicates in Array


java

import java.util.HashSet;

6/8
public class FindDuplicates {
public static void findDuplicates(int[] arr) {
HashSet<Integer> set = new HashSet<>();
for (int num : arr) {
if (!set.add(num)) {
System.out.println("Duplicate found: " + num);
}
}
}

public static void main(String[] args) {


int[] arr = {1, 2, 3, 4, 2, 5, 6, 1};
findDuplicates(arr);
}
}

🔹 Reverse a String
java

public class ReverseString {


public static void main(String[] args) {
String str = "Hello";
String reversed = new StringBuilder(str).reverse().toString();
System.out.println("Reversed: " + reversed);
}
}

📌 Output:
makefile

Reversed: olleH

7/8
Would you like more coding challenges or deeper
explanations on any topic?🚀

8/8

You might also like