0% found this document useful (0 votes)
26 views57 pages

Java Programming Mca

The document provides a comprehensive overview of Java programming, covering key concepts such as object-oriented programming principles, the Java ecosystem components (JDK, JRE, JVM), wrapper classes, inner classes, arrays, strings, access modifiers, and inheritance. It explains the functionality and usage of these concepts with examples, emphasizing Java's features like platform independence and automatic memory management. Additionally, it discusses the ListIterator interface in the context of Java collections, highlighting its bidirectional iteration capabilities.

Uploaded by

lpuclasses
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
26 views57 pages

Java Programming Mca

The document provides a comprehensive overview of Java programming, covering key concepts such as object-oriented programming principles, the Java ecosystem components (JDK, JRE, JVM), wrapper classes, inner classes, arrays, strings, access modifiers, and inheritance. It explains the functionality and usage of these concepts with examples, emphasizing Java's features like platform independence and automatic memory management. Additionally, it discusses the ListIterator interface in the context of Java collections, highlighting its bidirectional iteration capabilities.

Uploaded by

lpuclasses
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 57

PROGRAMMING IN JAVA

1. Introduction to Basic Java Concepts

Java is a high-level, object-oriented programming language developed by Sun Microsystems (now


owned by Oracle Corporation). It emphasizes portability, robustness, security, and platform
independence, following the "write once, run anywhere" (WORA) philosophy.

Key Java features:

 Object-Oriented Programming (OOP): Supports inheritance, polymorphism, encapsulation,


and abstraction.
 Platform Independence: Java code is compiled into bytecode, which can run on any system
with a JVM.
 Automatic Memory Management: Through garbage collection.
 Rich Standard Library: Extensive APIs across data structures, networking, GUI, and more.

2. JDK, JRE, and JVM

These components are foundational to the Java ecosystem:

a) JVM (Java Virtual Machine)

 Definition: An abstract computing machine that enables Java bytecode execution.


 Functionality:
o Loads .class files (compiled bytecode).
o Verifies and executes code using either an interpreter or a Just-In-Time (JIT) compiler.
o Manages runtime memory (heap, stack, method area).
 Platform-Specific: Although Java is platform-independent, the JVM is platform-dependent.

b) JRE (Java Runtime Environment)

 Definition: A package providing the environment required to run Java applications.


 Components:
o JVM
o Core libraries
o Other supporting files
 Note: Does not contain development tools like the compiler (javac).

c) JDK (Java Development Kit)

 Definition: A complete software development kit required for developing Java applications.
 Includes:
o JRE (hence includes the JVM)
o Development tools such as javac, javadoc, jdb, and other utilities
 Versions: Oracle provides standard and enterprise editions; open-source alternatives like
OpenJDK also exist.

Summary Table:

Component Contains Used For


JVM Bytecode interpreter Running Java bytecode
JRE JVM + Libraries Running Java applications
JDK JRE + Tools Developing Java applications

3. Wrapper Classes

Java is strictly object-oriented, and primitive types (e.g., int, double) are not objects. Wrapper
classes allow primitive types to be treated as objects.

a) Purpose:

 Enable primitives to be stored in collections (like ArrayList, which require objects).


 Provide utility methods (e.g., parsing strings to numbers).
 Enable use of generics and autoboxing/unboxing.

b) Key Wrapper Classes:

Primitive Wrapper Class


byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean

c) Example:

Integer x = 10; // autoboxing


int y = x; // unboxing

4. Inner and Nested Classes

Java supports classes defined within other classes or methods, primarily for better encapsulation and
logical grouping.

a) Nested Classes:
 All classes defined within another class.
 Two main types:
1. Static Nested Class
2. Non-static Inner Class

b) Types of Inner Classes:

Type Description
Member Inner Class Non-static, defined at class level
Anonymous Inner Class Class without a name, often used for one-time-use implementations
Local Inner Class Defined within a method or block
Static Nested Class Declared with static keyword; doesn't require enclosing class instance

Example:

class Outer {
private int data = 30;

class Inner {
void msg() { System.out.println("Data is " + data); }
}

static class StaticNested {


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

Use Cases:

 GUI programming (event handling).


 Logic encapsulation without polluting the top-level namespace.
 Creating closely coupled helper classes.

Arrays in Java

An array is a container object that holds a fixed number of values of a single type.

1. Declaring and Creating an Array

int[] numbers = new int[5]; // creates an array of 5 integers

2. Initializing an Array

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

3. Accessing Array Elements


System.out.println(numbers[2]); // Output: 30

4. Iterating through an Array

for (int i = 0; i < numbers.length; i++) {


System.out.println(numbers[i]);
}

Or using an enhanced for-loop:

for (int num : numbers) {


System.out.println(num);
}

✨ Strings in Java

A String in Java is an object that represents a sequence of characters.

1. Creating Strings

String greeting = "Hello, World!";

2. String Methods

System.out.println(greeting.length()); // 13
System.out.println(greeting.toUpperCase()); // "HELLO, WORLD!"
System.out.println(greeting.charAt(0)); // 'H'
System.out.println(greeting.substring(0, 5)); // "Hello"
System.out.println(greeting.contains("World")); // true

3. String Concatenation

String name = "Alice";


String message = "Hello, " + name + "!";
System.out.println(message); // "Hello, Alice!"

4. Comparing Strings

String a = "Java";
String b = "java";

System.out.println(a.equals(b)); // false (case-sensitive)


System.out.println(a.equalsIgnoreCase(b)); // true

� Mini Example: Count Vowels in a String


public class VowelCounter {
public static void main(String[] args) {
String str = "Hello World";
int count = 0;
for (int i = 0; i < str.length(); i++) {
char ch = Character.toLowerCase(str.charAt(i));
if (ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u') {
count++;
}
}
System.out.println("Number of vowels: " + count);
}
}

� 1. String (Immutable)

 Once a String object is created, it cannot be changed.


 Any operation that seems to modify a string actually creates a new object.

🔹 Example:

String s = "Hello";
s.concat(" World"); // This creates a new string but doesn't assign it
System.out.println(s); // Output: "Hello"

s = s.concat(" World"); // Now we assign the result


System.out.println(s); // Output: "Hello World"

✅ Use String when you have a fixed or rarely changed value.

🔗 2. StringBuffer (Mutable + Thread-safe)

 A StringBuffer can be modified without creating new objects.


 It is synchronized, so it's safe to use in multi-threaded environments.
 Slightly slower than StringBuilder because of the synchronization overhead.

🔹 Example:

StringBuffer sb = new StringBuffer("Hello");


sb.append(" World");
System.out.println(sb); // Output: "Hello World"

✅ Use StringBuffer when you need to modify strings in multi-threaded code.

⚡ 3. StringBuilder (Mutable + Not Thread-safe)

 Just like StringBuffer, but not synchronized.


 It is faster and preferred for single-threaded applications.
🔹 Example:

StringBuilder sb = new StringBuilder("Hello");


sb.append(" World");
System.out.println(sb); // Output: "Hello World"

✅ Use StringBuilder when you're building strings in loops or in single-threaded code.

Access Modifiers
Java access modifiers are used to specify the scope of the variables, data members,
methods, classes, or constructors. These help to restrict and secure the access (or,
level of access) of the data.

There are four different types of access modifiers in Java, we have listed them as
follows:

 Default (No keyword required)


 Private
 Protected
 Public

🔐 1. private

 The member is accessible only within the same class.


 Not visible to other classes, not even subclasses.

class Example {
private int data = 10;

private void show() {


System.out.println("Private method");
}
}

✅ Use when you want to encapsulate and protect data.

👪 2. default (no specifier)

 If no access specifier is mentioned, it's considered default.


 Accessible only within the same package.

class Example {
int data = 20; // default access
void show() {
System.out.println("Default access");
}
}

✅ Use when you want to allow access within the same package only.

👨👩👧 3. protected

 Accessible within the same package and also in subclasses (even if they are in different
packages).

class Example {
protected int data = 30;

protected void show() {


System.out.println("Protected method");
}
}

✅ Use when you want controlled inheritance with access in subclasses.

🌐 4. public

 Accessible from any class in any package.


 The least restrictive.

public class Example {


public int data = 40;

public void show() {


System.out.println("Public method");
}
}

✅ Use when you want maximum visibility, like public APIs.


Java Inheritance

In Java programming, the inheritance is an important of concept of Java OOPs. Inheritance is a


process where one class acquires the properties (methods and attributes) of another. With the use of
inheritance, the information is made manageable in a hierarchical order.

The class which inherits the properties of other is known as subclass (derived class, child class) and
the class whose properties are inherited is known as superclass (base class, parent class).

Need of Java Inheritance


 Code Reusability: The basic need of an inheritance is to reuse the features. If you have defined some
functionality once, by using the inheritance you can easily use them in other classes and packages.
 Extensibility: The inheritance helps to extend the functionalities of a class. If you have a base class with some
functionalities, you can extend them by using the inheritance in the derived class.
 Implantation of Method Overriding: Inheritance is required to achieve one of the concepts of Polymorphism
which is Method overriding.
 Achieving Abstraction: Another concept of OOPs that is abstraction also needs inheritance.

Implementation of Java Inheritance

To implement (use) inheritance in Java, the extends keyword is used. It inherits the properties
(attributes or/and methods) of the base class to the derived class. The word "extends" means to extend
functionalities i.e., the extensibility of the features.

Syntax to implement inheritance


Consider the below syntax to implement (use) inheritance in Java:

class Super {

.....

.....

class Sub extends Super {

.....

.....

Java Inheritance Example

Following is an example demonstrating Java inheritance. In this example, you can observe two
classes namely Calculation and My_Calculation.
Using extends keyword, the My_Calculation inherits the methods addition() and Subtraction() of
Calculation class.

Copy and paste the following program in a file with name My_Calculation.java

Java Program to Implement Inheritance


Open Compiler

class Calculation {

int z;

public void addition(int x, int y) {

z = x + y;

System.out.println("The sum of the given numbers:"+z);

public void Subtraction(int x, int y) {

z = x - y;

System.out.println("The difference between the given numbers:"+z);

public class My_Calculation extends Calculation {

public void multiplication(int x, int y) {

z = x * y;

System.out.println("The product of the given numbers:"+z);

public static void main(String args[]) {

int a = 20, b = 10;

My_Calculation demo = new My_Calculation();

demo.addition(a, b);
demo.Subtraction(a, b);

demo.multiplication(a, b);

javac My_Calculation.java
java My_Calculation
The sum of the given numbers:30
The difference between the given numbers:10
The product of the given numbers:200

In the given program, when an object to My_Calculation class is created, a copy of the contents of
the superclass is made within it. That is why, using the object of the subclass you can access the
members of a superclass.

The Superclass reference variable can hold the subclass object, but using that variable you can access
only the members of the superclass, so to access the members of both classes it is recommended to
always create reference variable to the subclass.

If you consider the above program, you can instantiate the class as given below. But using the
superclass reference variable ( cal in this case) you cannot call the method multiplication(), which
belongs to the subclass My_Calculation.

Calculation demo = new My_Calculation();


demo.addition(a, b);
demo.Subtraction(a, b);

Note − A subclass inherits all the members (fields, methods, and nested classes) from its superclass.
Constructors are not members, so they are not inherited by subclasses, but the constructor of the
superclass can be invoked from the subclass.
Java Inheritance: The super Keyword

The super keyword is similar to this keyword. Following are the scenarios where the super keyword
is used.

 It is used to differentiate the members of superclass from the members of subclass, if they have same
names.
 It is used to invoke the superclass constructor from subclass.

Differentiating the Members


If a class is inheriting the properties of another class. And if the members of the superclass have the
names same as the sub class, to differentiate these variables we use super keyword as shown below.

super.variable
super.method();

Sample Code
This section provides you a program that demonstrates the usage of the super keyword.

In the given program, you have two classes namely Sub_class and Super_class, both have a method
named display() with different implementations, and a variable named num with different values. We
are invoking display() method of both classes and printing the value of the variable num of both
classes. Here you can observe that we have used super keyword to differentiate the members of
superclass from subclass.

Copy and paste the program in a file with name Sub_class.java.

Example

Open Compiler

class Super_class {

int num = 20;

// display method of superclass

public void display() {

System.out.println("This is the display method of superclass");

}
public class Sub_class extends Super_class {

int num = 10;

// display method of sub class

public void display() {

System.out.println("This is the display method of subclass");

public void my_method() {

// Instantiating subclass

Sub_class sub = new Sub_class();

// Invoking the display() method of sub class

sub.display();

// Invoking the display() method of superclass

super.display();

// printing the value of variable num of subclass

System.out.println("value of the variable named num in sub class:"+ sub.num);

// printing the value of variable num of superclass

System.out.println("value of the variable named num in super class:"+ super.num);

public static void main(String args[]) {

Sub_class obj = new Sub_class();

obj.my_method();

}
}

Compile and execute the above code using the following syntax.

javac Super_Demo
java Super

On executing the program, you will get the following result −

Output

This is the display method of subclass


This is the display method of superclass
value of the variable named num in sub class:10
value of the variable named num in super class:20

Invoking Superclass Constructor

If a class is inheriting the properties of another class, the subclass automatically acquires the default
constructor of the superclass. But if you want to call a parameterized constructor of the superclass,
you need to use the super keyword as shown below.

super(values);

Sample Code
The program given in this section demonstrates how to use the super keyword to invoke the
parametrized constructor of the superclass. This program contains a superclass and a subclass, where
the superclass contains a parameterized constructor which accepts a integer value, and we used the
super keyword to invoke the parameterized constructor of the superclass.

Copy and paste the following program in a file with the name Subclass.java

Example

Open Compiler

Types of Java Inheritance

In Java, there are mainly three types of inheritances Single, Multilevel,


and Hierarchical. Java does not support Multiple and Hybrid inheritance.
Java ListIterator Interface
The ListIterator interface of the Java collections framework provides the
functionality to access elements of a list.
It is bidirectional. This means it allows us to iterate elements of a list in both the
direction.

It extends the Iterator interface.

The List interface provides a listIterator() method that returns an instance of the ListIterator interface.

Methods of ListIterator

The ListIterator interface provides methods that can be used to perform various operations on the elements
of a list.

hasNext() - returns true if there exists an element in the list

next() - returns the next element of the list

nextIndex() returns the index of the element that the next() method will return

previous() - returns the previous element of the list

previousIndex() - returns the index of the element that the previous() method will return

remove() - removes the element returned by either next() or previous()

set() - replaces the element returned by either next() or previous() with the specified element

Example 1: Implementation of ListIterator


In the example below, we have implemented the next(), nextIndex() and hasNext() methods of
the ListIterator interface in an array list.

import java.util.ArrayList;

import java.util.ListIterator;

class Main {

public static void main(String[] args) {

// Creating an ArrayList

ArrayList<Integer> numbers = new ArrayList<>();

numbers.add(1);

numbers.add(3);

numbers.add(2);

System.out.println("ArrayList: " + numbers);

// Creating an instance of ListIterator

ListIterator<Integer> iterate = numbers.listIterator();

// Using the next() method

int number1 = iterate.next();

System.out.println("Next Element: " + number1);

// Using the nextIndex()

int index1 = iterate.nextIndex();

System.out.println("Position of Next Element: " + index1);

// Using the hasNext() method

System.out.println("Is there any next element? " + iterate.hasNext());

Run Code
Output

ArrayList: [1, 3, 2]

Next Element: 1

Position of Next Element: 1

Is there any next element? true

Java LinkedList
The LinkedList class of the Java collections framework provides the functionality
of the linked list data structure (doubly linkedlist).

Each element in a linked list is known as a node. It consists of 3 fields:


Prev - stores an address of the previous element in the list. It is null for the first element

Next - stores an address of the next element in the list. It is null for the last element

Data - stores the actual data

Creating a Java LinkedList

Here is how we can create linked lists in Java:

LinkedList<Type> linkedList = new LinkedList<>();

Here, Type indicates the type of a linked list. For example,

// create Integer type linked list


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

// create String type linked list

LinkedList<String> linkedList = new LinkedList<>();

Example: Create LinkedList in Java

import java.util.LinkedList;

class Main {

public static void main(String[] args){

// create linkedlist

LinkedList<String> animals = new LinkedList<>();

// Add elements to LinkedList

animals.add("Dog");

animals.add("Cat");

animals.add("Cow");

System.out.println("LinkedList: " + animals);

Run Code

Output

LinkedList: [Dog, Cat, Cow]

Java TreeSet
The TreeSet class of the Java collections framework provides the functionality of a
tree data structure.
It extends the NavigableSet interface.

Creating a TreeSet

In order to create a tree set, we must import the java.util.TreeSet package first.

Once we import the package, here is how we can create a TreeSet in Java.

TreeSet<Integer> numbers = new TreeSet<>();

Here, we have created a TreeSet without any arguments. In this case, the elements in TreeSet are sorted
naturally (ascending order).

However, we can customize the sorting of elements by using the Comparator interface. We will learn about it
later in this tutorial.

Methods of TreeSet

The TreeSet class provides various methods that allow us to perform various operations on the set.

Insert Elements to TreeSet

add() - inserts the specified element to the set

addAll() - inserts all the elements of the specified collection to the set
For example,

import java.util.TreeSet;

class Main {

public static void main(String[] args) {

TreeSet<Integer> evenNumbers = new TreeSet<>();

// Using the add() method

evenNumbers.add(2);

evenNumbers.add(4);

evenNumbers.add(6);

System.out.println("TreeSet: " + evenNumbers);

TreeSet<Integer> numbers = new TreeSet<>();

numbers.add(1);

// Using the addAll() method

numbers.addAll(evenNumbers);

System.out.println("New TreeSet: " + numbers);

Run Code

Output

TreeSet: [2, 4, 6]

New TreeSet: [1, 2, 4, 6]


Remove Elements
 remove() - removes the specified element from the set
 removeAll() - removes all the elements from the set

Methods for Navigation


Since the TreeSet class implements NavigableSet , it provides various methods to
navigate over the elements of the tree set.
1. first() and last() Methods
 first() - returns the first element of the set
 last() - returns the last element of the set
2. ceiling(), floor(), higher() and lower() Methods
 higher(element) - Returns the lowest element among those elements that are
greater than the specified element .

 lower(element) - Returns the greatest element among those elements that are
less than the specified element .

 ceiling(element) - Returns the lowest element among those elements that are
greater than the specified element . If the element passed exists in a tree set, it
returns the element passed as an argument.
 floor(element) - Returns the greatest element among those elements that are
less than the specified element . If the element passed exists in a tree set, it returns
the element passed as an argument.
3. pollfirst() and pollLast() Methods
 pollFirst() - returns and removes the first element from the set
 pollLast() - returns and removes the last element from the set
4. headSet(), tailSet() and subSet() Methods
headSet(element, booleanValue)
The headSet() method returns all the elements of a tree set before the
specified element (which is passed as an argument).
The booleanValue parameter is optional. Its default value is false .

If true is passed as a booleanValue , the method returns all the elements before the
specified element including the specified element.

Other Methods of TreeSet


Method Description

clone() Creates a copy of the TreeSet

contains() Searches the TreeSet for the specified element and returns a boolean result

isEmpty() Checks if the TreeSet is empty

size() Returns the size of the TreeSet

clear() Removes all the elements from the TreeSet

Java PriorityQueue
The Java PriorityQueue class is an unbounded priority queue based on a priority heap.
Following are the important points about PriorityQueue −

 The elements of the priority queue are ordered according to their natural ordering, or
by a Comparator provided at queue construction time, depending on which
constructor is used.
 A priority queue does not permit null elements.
 A priority queue relying on natural ordering also does not permit insertion of non-
comparable objects.
Class declaration

Following is the declaration for java.util.PriorityQueue class −

public class PriorityQueue<E>


extends AbstractQueue<E>
implements Serializable

Parameters

Following is the parameter for java.util.PriorityQueue class −

E − This is the type of elements held in this collection.

Class constructors
Sr.No. Constructor & Description

PriorityQueue()
1 This creates a PriorityQueue with the default initial capacity (11) that
orders its elements according to their natural ordering.

PriorityQueue(Collection<? extends E> c)


2 This creates a PriorityQueue containing the elements in the specified
collection.

PriorityQueue(int initialCapacity)
3 This creates a PriorityQueue with the specified initial capacity that orders
its elements according to their natural ordering.

PriorityQueue(int initialCapacity, Comparator<? super E> comparator)


4 This creates a PriorityQueue with the specified initial capacity that orders
its elements according to the specified comparator.

PriorityQueue(PriorityQueue<? extends E> c)


5 This creates a PriorityQueue containing the elements in the specified
priority queue.

PriorityQueue(SortedSet<? extends E> c)


6 This creates a PriorityQueue containing the elements in the specified
sorted set.

Class methods
Sr.No. Method & Description
boolean add(E e)
1
This method inserts the specified element into this priority queue.

void clear()
2
This method removes all of the elements from this priority queue.

Comparator<? super E> comparator()


3 This method returns the comparator used to order the elements in this
queue, or null if this queue is sorted according to the natural ordering of
its elements.

boolean contains(Object o)
4
This method returns true if this queue contains the specified element.

void forEach(Consumer<? super E> action)


5 This method performs the given action for each element of the Iterable
until all elements have been processed or the action throws an
exception.

Iterator<E> iterator()
6
This method returns an iterator over the elements in this queue.

boolean offer(E e)
7
This method inserts the specified element into this priority queue.

boolean remove(Object o)
8
This method removes a single instance of the specified element from
this queue, if it is present.

boolean removeAll(Collection<?> c)
9
This method removes all of this collection's elements that are also
contained in the specified collection (optional operation).

boolean removeIf(Predicate<? super E> filter)


10
This method removes all of the elements of this collection that satisfy
the given predicate.

boolean retainAll(Collection<?> c)
11
This method retains only the elements in this collection that are
contained in the specified collection (optional operation).
Spliterator<E> spliterator()
12
This method creates a late-binding and fail-fast Spliterator over the
elements in this queue.

<T> T[] toArray(T[] a)


13 This method returns an array containing all of the elements in this
queue; the runtime type of the returned array is that of the specified
array.

Methods inherited

This class inherits methods from the following classes −

 java.util.AbstractQueue
 java.util.AbstractCollection
 java.util.Object
 java.util.Collection

Adding an Item to a Priority Queue Example

The following example shows the usage of Java PriorityQueue add(E) method to add
Integers. We're adding couple of Integers to the PriorityQueue object using add()
method calls per element and then print each element to show the elements added.

import java.util.PriorityQueue;

public class PriorityQueueDemo {

public static void main(String[] args) {

// create an empty priority queue with an initial capacity

PriorityQueue<Integer> queue = new PriorityQueue<>(5);

// use add() method to add elements in the queue

queue.add(20);

queue.add(30);

queue.add(20);

queue.add(30);
queue.add(15);

queue.add(22);

queue.add(11);

// let us print all the elements available in queue

for (Integer number : queue) {

System.out.println("Number = " + number);

Let us compile and run the above program, this will produce the following result −

Number = 11
Number = 20
Number = 15
Number = 30
Number = 30
Number = 22
Number = 20

Comparable and Comparator

✅ Comparable (java.lang.Comparable)

 Purpose: Defines the natural ordering of objects.


 How: You implement the Comparable<T> interface and override the compareTo() method in
your class.
 Used when: The object knows how to compare itself with another object of the same type.

Example:

public class Student implements Comparable<Student> {


int id;
String name;

public Student(int id, String name) {


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

@Override
public int compareTo(Student other) {
return this.id - other.id; // sort by id
}
}

Then you can sort like this:

Collections.sort(studentList); // uses compareTo()

✅ Comparator (java.util.Comparator)

 Purpose: Defines custom orderings, external to the object.


 How: You create a separate class (or use lambda/anonymous class) that implements
Comparator<T> and overrides compare().
 Used when: You want multiple ways to compare objects, or don’t want to modify the class
you're sorting.

Example:

class NameComparator implements Comparator<Student> {


@Override
public int compare(Student s1, Student s2) {
return s1.name.compareTo(s2.name);
}
}

Then:

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

Or, using lambdas (Java 8+):

studentList.sort((s1, s2) -> s1.name.compareTo(s2.name));

✅ What is the Properties class?

 It's part of java.util.


 Basically a subclass of Hashtable<Object, Object>, but it's specifically used to manage
key-value pairs where both keys and values are Strings.
 Commonly used to read/write configuration files like .properties files.

✅ Typical Use Cases


 Storing app settings (e.g. database URL, username, password).
 Loading configurations from .properties files.
 Writing updated settings back to a file.

✅ Basic Example: Loading Properties from a File

Let's say you have a file called config.properties:

db.url=jdbc:mysql://localhost:3306/mydb
db.user=root
db.password=12345

Java code to load it:

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;

public class ConfigLoader {


public static void main(String[] args) {
Properties props = new Properties();
try (FileInputStream fis = new FileInputStream("config.properties")) {
props.load(fis);
String url = props.getProperty("db.url");
String user = props.getProperty("db.user");
String password = props.getProperty("db.password");

System.out.println("URL: " + url);


System.out.println("User: " + user);
System.out.println("Password: " + password);
} catch (IOException e) {
e.printStackTrace();
}
}
}

✅ Storing/Writing Properties to a File

You can also create or modify properties and save them:

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;

public class SaveProperties {


public static void main(String[] args) {
Properties props = new Properties();
props.setProperty("app.name", "MyCoolApp");
props.setProperty("app.version", "1.0");
try (FileOutputStream fos = new FileOutputStream("app.properties")) {
props.store(fos, "App Settings");
} catch (IOException e) {
e.printStackTrace();
}
}
}

lambda expressions
Lambda expression is, essentially, an anonymous or unnamed method. The
lambda expression does not execute on its own. Instead, it is used to implement a
method defined by a functional interface.

How to define lambda expression in Java?


Here is how we can define lambda expression in Java.

(parameter list) -> lambda body

The new operator ( -> ) used is known as an arrow operator or a lambda operator.
The syntax might not be clear at the moment. Let's explore some examples,
Suppose, we have a method like this:

double getPiValue() {
return 3.1415;
}

We can write this method using lambda expression as:

() -> 3.1415

Here, the method does not have any parameters. Hence, the left side of the
operator includes an empty parameter. The right side is the lambda body that
specifies the action of the lambda expression. In this case, it returns the value

Types of Lambda Body


In Java, the lambda body is of two types.

1. A body with a single expression

() -> System.out.println("Lambdas are great");

This type of lambda body is known as the expression body.

2. A body that consists of a block of code.

() -> {
double pi = 3.1415;
return pi;
};

This type of the lambda body is known as a block body. The block body allows the
lambda body to include multiple statements. These statements are enclosed
inside the braces and you have to add a semi-colon after the braces.

Note: For the block body, you can have a return statement if the body returns a
value. However, the expression body does not require a return statement.

Example 3: Lambda Expression


Let's write a Java program that returns the value of Pi using the lambda
expression.

As mentioned earlier, a lambda expression is not executed on its own. Rather, it


forms the implementation of the abstract method defined by the functional
interface.

So, we need to define a functional interface first.


import java.lang.FunctionalInterface;

// this is functional interface


@FunctionalInterface
interface MyInterface{

// abstract method
double getPiValue();
}

public class Main {

public static void main( String[] args ) {

// declare a reference to MyInterface


MyInterface ref;

// lambda expression
ref = () -> 3.1415;

System.out.println("Value of Pi = " + ref.getPiValue());


}
}
Run Code

Output:

Value of Pi = 3.1415

In the above example,

 We have created a functional interface named MyInterface . It contains a single


abstract method named getPiValue()

 Inside the Main class, we have declared a reference to MyInterface . Note that we
can declare a reference of an interface but we cannot instantiate an interface.
That is,

 // it will throw an error


 MyInterface ref = new myInterface();

 // it is valid

MyInterface ref;

 We then assigned a lambda expression to the reference.

ref = () -> 3.1415;

 Finally, we call the method getPiValue() using the reference interface. When

System.out.println("Value of Pi = " + ref.getPiValue());

Lambda Expressions with parameters


Till now we have created lambda expressions without any parameters. However,
similar to methods, lambda expressions can also have parameters. For example,

(n) -> (n%2)==0

Life Cycle of a Thread in Java

The life cycle of a thread in Java refers to the various states of a thread goes
through. For example, a thread is born, started, runs, and then dies. Thread
class defines the life cycle and various states of a thread.

Flow Chart of Java Thread Life Cycle

The following diagram shows the complete life cycle of a thread.


States of a Thread Life Cycle in Java

Following are the stages of the life cycle −

 New − A new thread begins its life cycle in the new state. It remains in this state until
the program starts the thread. It is also referred to as a born thread.
 Runnable − After a newly born thread is started, the thread becomes runnable. A
thread in this state is considered to be executing its task.
 Waiting − Sometimes, a thread transitions to the waiting state while the thread waits
for another thread to perform a task. A thread transitions back to the runnable state
only when another thread signals the waiting thread to continue executing.
 Timed Waiting − A runnable thread can enter the timed waiting state for a specified
interval of time. A thread in this state transitions back to the runnable state when
that time interval expires or when the event it is waiting for occurs.
 Terminated (Dead) − A runnable thread enters the terminated state when it completes
its task or otherwise terminates.

Java Example for Demonstrating Thread States

In this example, we're creating two threads by extending the Thread class. We're
printing each state of the thread. When a thread object is created, its state is NEW;
when start() method is called, state is START; when run() method is called, state is
RUNNING; When a thread finished the processing the run() method, it went to
DEAD state.

class ThreadDemo extends Thread {


private Thread t;

private String threadName;

ThreadDemo( String name) {

threadName = name;

System.out.println("Thread: " + threadName + ", " + "State: New");

public void run() {

System.out.println("Thread: " + threadName + ", " + "State: Running");

for(int i = 4; i > 0; i--) {

System.out.println("Thread: " + threadName + ", " + i);

System.out.println("Thread: " + threadName + ", " + "State: Dead");

public void start () {

System.out.println("Thread: " + threadName + ", " + "State: Start");

if (t == null) {

t = new Thread (this, threadName);

t.start ();

public class TestThread {

public static void main(String args[]) {

ThreadDemo thread1 = new ThreadDemo( "Thread-1");

ThreadDemo thread2 = new ThreadDemo( "Thread-2");

thread1.start();

thread2.start();

}
Output

Thread: Thread-1, State: New


Thread: Thread-2, State: New
Thread: Thread-1, State: Start
Thread: Thread-2, State: Start
Thread: Thread-1, State: Running
Thread: Thread-2, State: Running
Thread: Thread-2, 4
Thread: Thread-2, 3
Thread: Thread-2, 2
Thread: Thread-2, 1
Thread: Thread-2, State: Dead
Thread: Thread-1, 4
Thread: Thread-1, 3
Thread: Thread-1, 2
Thread: Thread-1, 1
Thread: Thread-1, State: Dead

🔁 1. Suspending and Resuming Threads in Java

🚫 Deprecated Approach (Dangerous)

Java used to offer methods like Thread.suspend() and Thread.resume(), but they are now
deprecated because they could lead to deadlocks and thread starvation.

Thread t = new Thread(() -> {


while (true) {
System.out.println("Running...");
}
});
t.start();
t.suspend(); // ❌ Deprecated
t.resume(); // ❌ Deprecated

❗ These methods can leave locks held, and prevent other threads from making progress.

✅ Safe Approach Using a Volatile Flag with wait()/notify()


class ControlledThread extends Thread {
private volatile boolean suspended = false;

public void run() {


while (true) {
synchronized (this) {
while (suspended) {
try {
wait(); // Thread waits here
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.out.println("Interrupted while suspended");
return;
}
}
}

// Simulated task
System.out.println("Thread is working...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("Thread interrupted during work.");
return;
}
}
}

public synchronized void suspendThread() {


suspended = true;
}

public synchronized void resumeThread() {


suspended = false;
notify();
}
}

✅ Usage:
public class Main {
public static void main(String[] args) throws InterruptedException {
ControlledThread t = new ControlledThread();
t.start();

Thread.sleep(3000);
t.suspendThread();

System.out.println("Thread suspended.");
Thread.sleep(3000);

t.resumeThread();
System.out.println("Thread resumed.");
}
}
❌ 2. Stopping Threads in Java

🚫 Deprecated Method: Thread.stop()


Thread t = new Thread(() -> {
while (true) {
// Doing work
}
});
t.start();
t.stop(); // ❌ Dangerous!

❗ Stops the thread immediately, potentially leaving shared resources in an inconsistent state.

✅ Safe Way: Using a Volatile Flag


class StoppableThread extends Thread {
private volatile boolean running = true;

public void run() {


while (running) {
System.out.println("Thread running safely...");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.out.println("Interrupted!");
break;
}
}
System.out.println("Thread exiting gracefully.");
}

public void stopThread() {


running = false;
}
}

✅ Usage:
public class Main {
public static void main(String[] args) throws InterruptedException {
StoppableThread t = new StoppableThread();
t.start();

Thread.sleep(2000);
t.stopThread(); // Signal to stop
}
}
✅ Alternative Way: Using interrupt()
class InterruptExample extends Thread {
public void run() {
while (!Thread.currentThread().isInterrupted()) {
System.out.println("Working...");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
System.out.println("Thread was interrupted!");
break;
}
}
}
}

✅ Usage:
InterruptExample t = new InterruptExample();
t.start();
Thread.sleep(2000);
t.interrupt(); // Gracefully stop

🔒 3. Deadlock in Java

💥 What is Deadlock?

Deadlock happens when two or more threads are waiting for each other to release a resource, and
none of them can proceed.

� Deadlock Example in Java


class A {
synchronized void methodA(B b) {
System.out.println("Thread-1: Holding lock on A...");
try { Thread.sleep(100); } catch (InterruptedException e) {}
System.out.println("Thread-1: Waiting for lock on B...");
b.last(); // tries to get lock on B
}

synchronized void last() {


System.out.println("Inside A.last()");
}
}

class B {
synchronized void methodB(A a) {
System.out.println("Thread-2: Holding lock on B...");
try { Thread.sleep(100); } catch (InterruptedException e) {}
System.out.println("Thread-2: Waiting for lock on A...");
a.last(); // tries to get lock on A
}

synchronized void last() {


System.out.println("Inside B.last()");
}
}
public class DeadlockDemo {
public static void main(String[] args) {
A a = new A();
B b = new B();

new Thread(() -> a.methodA(b)).start();


new Thread(() -> b.methodB(a)).start();
}
}

🛑 Output (Typical):

Thread-1: Holding lock on A...


Thread-2: Holding lock on B...
Thread-1: Waiting for lock on B...
Thread-2: Waiting for lock on A...

Both threads are now stuck → deadlock.

✅ Preventing Deadlocks

🔐 1. Lock Ordering

Always acquire multiple locks in the same order.

class Safe {
private final Object lock1 = new Object();
private final Object lock2 = new Object();

public void method1() {


synchronized (lock1) {
synchronized (lock2) {
// Safe
}
}
}

public void method2() {


synchronized (lock1) { // Same order as method1
synchronized (lock2) {
// Safe
}
}
}
}
🔄 2. Using ReentrantLock.tryLock() with Timeout

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.TimeUnit;

class SafeLock {
private final Lock lock1 = new ReentrantLock();
private final Lock lock2 = new ReentrantLock();

public void doWork() {


try {
if (lock1.tryLock(50, TimeUnit.MILLISECONDS)) {
try {
if (lock2.tryLock(50, TimeUnit.MILLISECONDS)) {
try {
// Safe critical section
} finally {
lock2.unlock();
}
}
} finally {
lock1.unlock();
}
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}

☠️ What Happens When an Exception Is Thrown in a Thread?

If an exception (like NullPointerException, IOException, etc.) is thrown inside a thread and not
caught, it will terminate that thread—but not the entire program (unless it’s the main thread or
you're relying on the thread to complete a critical task).

✅ How to Handle Exceptions in Threads

1. Handle Exceptions Within the Thread Itself

The simplest and safest way is to wrap your thread logic in a try-catch block.

class MyThread extends Thread {


public void run() {
try {
// Thread logic
System.out.println("Thread running...");
int result = 10 / 0; // This will cause ArithmeticException
} catch (Exception e) {
System.out.println("Exception caught in thread: " + e);
}
}
}

2. Use UncaughtExceptionHandler

Java provides a way to catch exceptions that were not caught inside the thread itself using
Thread.UncaughtExceptionHandler.

class MyThread extends Thread {


public void run() {
System.out.println("Thread will throw exception...");
throw new RuntimeException("Oops!");
}
}

public class Main {


public static void main(String[] args) {
MyThread t = new MyThread();

t.setUncaughtExceptionHandler((thread, ex) -> {


System.out.println("Caught exception from thread: " +
thread.getName() + " - " + ex.getMessage());
});

t.start();
}
}

This is useful for logging or alerting when something goes wrong unexpectedly in background
threads.

3. Handling Exceptions in Thread Pools (Executors)

If you're using ExecutorService (e.g., via Executors.newFixedThreadPool()), exceptions are


wrapped in the Future object. You have to explicitly call get() to retrieve the exception.

ExecutorService executor = Executors.newSingleThreadExecutor();

Future<?> future = executor.submit(() -> {


throw new RuntimeException("Error inside task!");
});

try {
future.get(); // this will throw ExecutionException
} catch (ExecutionException e) {
System.out.println("Caught: " + e.getCause()); // e.getCause() gives the
actual exception
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}

✅ Tip: Always check exceptions from submitted tasks via Future.

4. Custom ThreadFactory (Advanced Use)

You can use a custom ThreadFactory to apply a common UncaughtExceptionHandler to all


threads created by an ExecutorService.

ThreadFactory factory = runnable -> {


Thread t = new Thread(runnable);
t.setUncaughtExceptionHandler((th, ex) -> {
System.out.println("Handled in factory: " + ex.getMessage());
});
return t;
};

ExecutorService executor = Executors.newFixedThreadPool(2, factory);

executor.submit(() -> {
throw new RuntimeException("Boom!");
});

☑️ JButton — Push Button

Used to perform an action when clicked.

🔹 Example:
import javax.swing.*;

public class JButtonExample {


public static void main(String[] args) {
JFrame frame = new JFrame("JButton Example");
JButton button = new JButton("Click Me");

button.addActionListener(e -> JOptionPane.showMessageDialog(frame,


"Button Clicked!"));

frame.add(button);
frame.setSize(300, 200);
frame.setLayout(null);
button.setBounds(100, 80, 100, 30);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
🔘 JRadioButton — Radio Button

Allows single selection among a group.

🔹 Example:
import javax.swing.*;

public class JRadioButtonExample {


public static void main(String[] args) {
JFrame frame = new JFrame("JRadioButton Example");

JRadioButton rb1 = new JRadioButton("Male");


JRadioButton rb2 = new JRadioButton("Female");

rb1.setBounds(100, 50, 100, 30);


rb2.setBounds(100, 80, 100, 30);

ButtonGroup group = new ButtonGroup(); // Group to allow single


selection
group.add(rb1);
group.add(rb2);

frame.add(rb1);
frame.add(rb2);
frame.setSize(300, 200);
frame.setLayout(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}

📝 JTextArea — Multi-line Text Input

Allows input/output of multiple lines of text.

🔹 Example:
import javax.swing.*;

public class JTextAreaExample {


public static void main(String[] args) {
JFrame frame = new JFrame("JTextArea Example");

JTextArea area = new JTextArea("Type something here...");


area.setBounds(50, 50, 200, 100);

frame.add(area);
frame.setSize(300, 250);
frame.setLayout(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}

📑 JComboBox — Drop-down Menu

Provides a menu with selectable items.

🔹 Example:
import javax.swing.*;

public class JComboBoxExample {


public static void main(String[] args) {
JFrame frame = new JFrame("JComboBox Example");

String[] courses = {"Java", "Python", "C++", "Kotlin"};


JComboBox<String> comboBox = new JComboBox<>(courses);
comboBox.setBounds(50, 50, 150, 30);

frame.add(comboBox);
frame.setSize(300, 200);
frame.setLayout(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}

📊 JTable — Displaying Tabular Data

Displays data in a grid format (rows and columns).

🔹 Example:
import javax.swing.*;

public class JTableExample {


public static void main(String[] args) {
JFrame frame = new JFrame("JTable Example");

String[][] data = {
{"101", "Alice", "90"},
{"102", "Bob", "85"},
{"103", "Charlie", "95"}
};

String[] column = {"ID", "Name", "Marks"};

JTable table = new JTable(data, column);


JScrollPane sp = new JScrollPane(table);
sp.setBounds(20, 20, 250, 100);

frame.add(sp);
frame.setSize(300, 200);
frame.setLayout(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}

🎨 JColorChooser — Color Picker Dialog

Allows users to pick a color from a palette.

🔹 Example:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class JColorChooserExample {


public static void main(String[] args) {
JFrame frame = new JFrame("JColorChooser Example");
JButton button = new JButton("Choose Color");
JLabel label = new JLabel("Color will appear here");
label.setBounds(50, 100, 200, 30);

button.setBounds(50, 50, 150, 30);


button.addActionListener(e -> {
Color color = JColorChooser.showDialog(frame, "Pick a Color",
Color.white);
if (color != null) {
label.setForeground(color);
}
});

frame.add(button);
frame.add(label);
frame.setSize(300, 200);
frame.setLayout(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}

📊 JProgressBar — Visual Progress Indicator

Displays task progress (e.g., loading, downloading).

🔹 Example:
import javax.swing.*;

public class JProgressBarExample {


public static void main(String[] args) {
JFrame frame = new JFrame("JProgressBar Example");

JProgressBar progressBar = new JProgressBar(0, 100);


progressBar.setBounds(50, 50, 200, 30);
progressBar.setValue(0);
progressBar.setStringPainted(true); // Shows percentage

frame.add(progressBar);
frame.setSize(300, 150);
frame.setLayout(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);

// Simulate progress
for (int i = 0; i <= 100; i++) {
try {
Thread.sleep(50); // delay
progressBar.setValue(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

🎚️ JSlider — Value Slider (Horizontal/Vertical)

Lets the user choose a numeric value by sliding a knob.

🔹 Example:
import javax.swing.*;
import javax.swing.event.*;

public class JSliderExample {


public static void main(String[] args) {
JFrame frame = new JFrame("JSlider Example");

JLabel label = new JLabel("Value: 50");


label.setBounds(100, 100, 200, 30);

JSlider slider = new JSlider(0, 100, 50); // min, max, initial value
slider.setBounds(50, 50, 200, 40);
slider.setMajorTickSpacing(25);
slider.setPaintTicks(true);
slider.setPaintLabels(true);

slider.addChangeListener(e -> label.setText("Value: " +


slider.getValue()));

frame.add(slider);
frame.add(label);
frame.setSize(300, 200);
frame.setLayout(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}

📦 What is a Layout Manager?

A layout manager is an object that determines the size and position of components within a
container. It automates the placement of UI components so you don’t have to manually set
setBounds().

You set the layout using:

container.setLayout(new LayoutManagerType());

🌐 1. BorderLayout (Default for JFrame)

Divides the container into 5 regions:

 NORTH
 SOUTH
 EAST
 WEST
 CENTER

🔹 Example:
import javax.swing.*;
import java.awt.*;

public class BorderLayoutExample {


public static void main(String[] args) {
JFrame frame = new JFrame("BorderLayout");
frame.setLayout(new BorderLayout());

frame.add(new JButton("North"), BorderLayout.NORTH);


frame.add(new JButton("South"), BorderLayout.SOUTH);
frame.add(new JButton("East"), BorderLayout.EAST);
frame.add(new JButton("West"), BorderLayout.WEST);
frame.add(new JButton("Center"), BorderLayout.CENTER);

frame.setSize(400, 300);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
🔲 2. GridLayout

Divides container into a grid of rows and columns, and all components get equal size.

🔹 Example:
import javax.swing.*;
import java.awt.*;

public class GridLayoutExample {


public static void main(String[] args) {
JFrame frame = new JFrame("GridLayout");
frame.setLayout(new GridLayout(2, 3)); // 2 rows, 3 columns

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


frame.add(new JButton("Button " + i));
}

frame.setSize(400, 200);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}

➡️ 3. FlowLayout

Places components left to right, like words in a sentence, wrapping to next line as needed. It's the
default for JPanel.

🔹 Example:
import javax.swing.*;
import java.awt.*;

public class FlowLayoutExample {


public static void main(String[] args) {
JFrame frame = new JFrame("FlowLayout");
frame.setLayout(new FlowLayout(FlowLayout.LEFT)); // LEFT, CENTER, RIGHT

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


frame.add(new JButton("Button " + i));
}

frame.setSize(300, 200);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
📦 4. BoxLayout

Lays out components in a single row (X_AXIS) or a single column (Y_AXIS).

🔹 Example (Vertical Layout):


import javax.swing.*;
import java.awt.*;

public class BoxLayoutExample {


public static void main(String[] args) {
JFrame frame = new JFrame("BoxLayout");
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); // vertical

panel.add(new JButton("Button 1"));


panel.add(Box.createRigidArea(new Dimension(0, 10))); // spacer
panel.add(new JButton("Button 2"));
panel.add(new JButton("Button 3"));

frame.add(panel);
frame.setSize(200, 200);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}

🃏 5. CardLayout

Like a deck of cards—only one component is visible at a time. Used in wizards, tabbed UIs, etc.

🔹 Example:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class CardLayoutExample {


public static void main(String[] args) {
JFrame frame = new JFrame("CardLayout");
CardLayout card = new CardLayout();
JPanel cardPanel = new JPanel(card);

JPanel card1 = new JPanel();


card1.add(new JLabel("This is Card 1"));

JPanel card2 = new JPanel();


card2.add(new JLabel("This is Card 2"));

cardPanel.add(card1, "Card1");
cardPanel.add(card2, "Card2");

JButton switchBtn = new JButton("Switch Card");


switchBtn.addActionListener(e -> card.next(cardPanel));

frame.setLayout(new BorderLayout());
frame.add(cardPanel, BorderLayout.CENTER);
frame.add(switchBtn, BorderLayout.SOUTH);

frame.setSize(300, 200);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}

🔌 Introduction to JDBC

JDBC (Java Database Connectivity) is an API that enables Java applications to interact with
databases using SQL queries. It acts as a bridge between a Java program and a database.

🔧 JDBC Workflow (Steps):

1. Load JDBC driver


2. Establish a connection
3. Create a statement
4. Execute SQL query
5. Process the result
6. Close the connection

� Basic Example: JDBC with MySQL


import java.sql.*;

public class JdbcExample {


public static void main(String[] args) {
try {
// 1. Load driver
Class.forName("com.mysql.cj.jdbc.Driver");

// 2. Connect to DB
Connection con = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/testdb", "root", "yourpassword");

// 3. Create Statement
Statement stmt = con.createStatement();

// 4. Execute Query
ResultSet rs = stmt.executeQuery("SELECT * FROM students");

// 5. Process Result
while (rs.next()) {
System.out.println(rs.getInt(1) + " " + rs.getString(2));
}

// 6. Close connection
con.close();

} catch (Exception e) {
System.out.println(e);
}
}
}

Make sure:

 MySQL is running
 You have a database named testdb
 Table students exists
 JDBC driver (mysql-connector-java) is in your classpath

⚙️ CRUD Operations (Create, Read, Update, Delete)

Let’s look at how to do each using PreparedStatement (safer and prevents SQL injection):

1�⃣ Create (INSERT)


PreparedStatement ps = con.prepareStatement("INSERT INTO students VALUES (?,
?)");
ps.setInt(1, 101);
ps.setString(2, "Alice");
ps.executeUpdate();

2�⃣ Read (SELECT)


PreparedStatement ps = con.prepareStatement("SELECT * FROM students");
ResultSet rs = ps.executeQuery();
while (rs.next()) {
System.out.println(rs.getInt(1) + " " + rs.getString(2));
}

3�⃣ Update
PreparedStatement ps = con.prepareStatement("UPDATE students SET name=? WHERE
id=?");
ps.setString(1, "Bob");
ps.setInt(2, 101);
ps.executeUpdate();

4�⃣ Delete
PreparedStatement ps = con.prepareStatement("DELETE FROM students WHERE id=?");
ps.setInt(1, 101);
ps.executeUpdate();
🔌 Connection Interface

The Connection interface represents a session with a specific database. It's part of java.sql.

🔑 Key Methods:

Method Description

createStatement() Creates a basic SQL statement

prepareStatement(String sql) Creates a precompiled SQL statement

close() Closes the connection

commit() Commits a transaction

rollback() Rolls back a transaction

You're on a roll! Let's get into Java Networking, especially the key terminology, the Socket classes,
and how to create client-server communication using Socket and ServerSocket.

🌐 Java Network Terminology


Term Meaning

IP Address Unique number to identify a device on a network

A logical channel between client and server for communication (e.g., port
Port
80 for HTTP)

Protocol Set of rules for communication (e.g., TCP, UDP, HTTP)

TCP (Transmission Control


Reliable, connection-based communication
Protocol)

UDP (User Datagram Protocol) Fast, connectionless, but unreliable

Socket Endpoint for sending/receiving data between machines

Client Program that requests data

Server Program that listens and responds to clients


🔌 Socket Classes in Java

Java provides the java.net package for networking.

🔹 Socket Class (Client Side)

Used by the client to connect to a server.

Constructor:

Socket s = new Socket("localhost", 6666);

🔹 ServerSocket Class (Server Side)

Listens for incoming connections.

Constructor:

ServerSocket ss = new ServerSocket(6666);

� Basic Client-Server Example (TCP)

🖥� Server Program:
import java.io.*;
import java.net.*;

public class MyServer {


public static void main(String[] args) {
try {
ServerSocket ss = new ServerSocket(6666); // server on port 6666
Socket s = ss.accept(); // waits for client

DataInputStream dis = new DataInputStream(s.getInputStream());


String str = dis.readUTF();
System.out.println("Client says: " + str);

ss.close();
} catch (Exception e) {
System.out.println(e);
}
}
}

💻 Client Program:
import java.io.*;
import java.net.*;

public class MyClient {


public static void main(String[] args) {
try {
Socket s = new Socket("localhost", 6666);

DataOutputStream dos = new DataOutputStream(s.getOutputStream());


dos.writeUTF("Hello Server");

dos.flush();
dos.close();
s.close();
} catch (Exception e) {
System.out.println(e);
}
}
}

️ Pro Tip: Run the server first, then the client, or the client won’t find the server.

📚 Important Methods and Classes

🔑 Socket Class (Client):

Method Description

getInputStream() Reads from server

getOutputStream() Sends data to server

close() Closes socket

🔑 ServerSocket Class (Server):

Method Description

accept() Waits for a client to connect

close() Closes the server socket

Great! You're covering all the key areas of Java Networking. Let’s break it down:

🌐 URL Class — Handling Web Addresses

The URL class in java.net is used to handle Uniform Resource Locators, like web addresses.
🔹 Example:
import java.net.*;
import java.io.*;

public class URLExample {


public static void main(String[] args) throws Exception {
URL url = new URL("https://example.com");

System.out.println("Protocol: " + url.getProtocol());


System.out.println("Host: " + url.getHost());
System.out.println("File: " + url.getFile());
System.out.println("Port: " + url.getPort());
}
}

🔗 URLConnection Class — Reading from Web Resources

The URLConnection class helps open connections and read data from a URL.

🔹 Example: Reading HTML from a Website


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

public class URLConnectionExample {


public static void main(String[] args) throws Exception {
URL url = new URL("https://example.com");
URLConnection conn = url.openConnection();

BufferedReader br = new BufferedReader(new


InputStreamReader(conn.getInputStream()));

String inputLine;
while ((inputLine = br.readLine()) != null) {
System.out.println(inputLine);
}

br.close();
}
}

📤📥 DatagramSocket & DatagramPacket — UDP Programming

Unlike TCP, UDP is faster but unreliable and uses DatagramSocket and DatagramPacket.

🖥� Server: DatagramSocket Example


import java.net.*;

public class UDPServer {


public static void main(String[] args) throws Exception {
DatagramSocket ds = new DatagramSocket(3000);
byte[] buffer = new byte[1024];

DatagramPacket dp = new DatagramPacket(buffer, buffer.length);


ds.receive(dp); // Wait for packet

String msg = new String(dp.getData(), 0, dp.getLength());


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

ds.close();
}
}

💻 Client:
import java.net.*;

public class UDPClient {


public static void main(String[] args) throws Exception {
DatagramSocket ds = new DatagramSocket();

String str = "Hello UDP Server";


InetAddress ip = InetAddress.getByName("localhost");

DatagramPacket dp = new DatagramPacket(str.getBytes(), str.length(), ip,


3000);
ds.send(dp);

ds.close();
}
}

🔌 Java Socket Programming (TCP Recap)

TCP is reliable and connection-based.

� Server (Recap from before):


ServerSocket ss = new ServerSocket(6666);
Socket s = ss.accept(); // Waits for client

💬 Client:
Socket s = new Socket("localhost", 6666);

🔧 When to Use Which


Class / Concept Use For

Socket / ServerSocket Reliable 2-way connection (TCP)


Class / Concept Use For

DatagramSocket Fast, connectionless communication (UDP)

URL / URLConnection Accessing websites or APIs

You might also like