[go: up one dir, main page]

0% found this document useful (0 votes)
11 views46 pages

Java Note

The document provides a detailed overview of the Java Collection Framework, including key interfaces such as Collection, List, Set, Queue, Deque, and Map, along with their methods and implementations. It also covers exception handling in Java, explaining checked and unchecked exceptions, and the use of keywords like try-catch, finally, throw, and throws. Additionally, it discusses Java I/O streams and basic file operations using the File class.

Uploaded by

Milan
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)
11 views46 pages

Java Note

The document provides a detailed overview of the Java Collection Framework, including key interfaces such as Collection, List, Set, Queue, Deque, and Map, along with their methods and implementations. It also covers exception handling in Java, explaining checked and unchecked exceptions, and the use of keywords like try-catch, finally, throw, and throws. Additionally, it discusses Java I/O streams and basic file operations using the File class.

Uploaded by

Milan
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/ 46

Java Collection Framework - Detailed

Notes
1. Collection Interface (Root Interface)
The Collection interface is the root of the Java Collection Framework. It represents a
group of objects and provides basic methods to work with collections.

• Key Methods:
o add(E e): Adds an element to the collection.
o remove(Object o): Removes an element.
o size(): Returns the size of the collection.
o isEmpty(): Checks if the collection is empty.
o iterator(): Returns an iterator for the collection.

This interface is extended by List, Set, Queue, and Deque.

2. List Interface (Ordered Collection with Duplicates


Allowed)
The List interface represents an ordered collection that allows duplicate elements.
Elements are stored by index.

Method Description Supported By


add(E e) Adds an element. All Lists
add(int index, E element) Inserts at a given index. ArrayList, LinkedList,
Vector
get(int index) Retrieves an element by All Lists
index.
set(int index, E element) Updates an element. All Lists
remove(int index) Removes an element by All Lists
index.
indexOf(Object o) Returns first index of an All Lists
element.
contains(Object o) Checks if the element All Lists
exists.
sort(Comparator<? super Sorts elements. ArrayList, LinkedList,
E> c) Vector

Implementations of List:

1. ArrayList (Dynamic Array)


a. Uses a dynamic array to store elements.
b. Fast random access (O(1)), but slow insertions/deletions in the middle
(O(n)).
c. Not synchronized.

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


arrayList.add("Apple");
arrayList.add("Banana");
System.out.println(arrayList.get(0)); // Apple

2. LinkedList (Doubly Linked List)


a. Stores elements as nodes, where each node has references to the
previous and next node.
b. Faster insertions/deletions (O(1)) compared to ArrayList, but slower
random access (O(n)).
c. Can be used as a Queue or Deque.

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


linkedList.add(1);
linkedList.add(2);
System.out.println(linkedList.get(1)); // 2

3. Vector (Synchronized Version of ArrayList)


a. Similar to ArrayList, but thread-safe (synchronized).
b. Slower due to synchronization overhead.
4. Stack (LIFO - Last In First Out)
a. Extends Vector.
b. Used for stack operations (push, pop, peek).

Stack<Integer> stack = new Stack<>();


stack.push(10);
stack.push(20);
System.out.println(stack.pop()); // 20

3. Set Interface (Unique Elements, No Order


Guaranteed)
A Set does not allow duplicate elements. It is useful when uniqueness is required.

Method Description Supported By


add(E e) Adds an element if not already All Sets
present.
remove(Object o) Removes an element. All Sets
contains(Object o) Checks if an element exists. All Sets
size() Returns the number of elements. All Sets
iterator() Returns an iterator. All Sets

Implementations of Set:

1. HashSet (Unordered Set)


a. Uses a hash table.
b. No guaranteed order.
c. Fast insertions, deletions, and lookups (O(1)).

Set<String> hashSet = new HashSet<>();


hashSet.add("Dog");
hashSet.add("Cat");
System.out.println(hashSet); // Order is unpredictable

2. LinkedHashSet (Maintains Insertion Order)


a. Like HashSet, but maintains insertion order.
3. TreeSet (Sorted Set)
a. Uses a Red-Black tree.
b. Elements are sorted in natural order.
c. Slower than HashSet (O(log n) operations).

Set<Integer> treeSet = new TreeSet<>();


treeSet.add(3);
treeSet.add(1);
treeSet.add(2);
System.out.println(treeSet); // [1, 2, 3]

4. Queue Interface (FIFO - First In First Out)


A Queue is used for processing elements in a FIFO manner.

Method Description Supported By


offer(E Adds an element (returns false if full). LinkedList,
e) PriorityQueue
poll() Retrieves and removes head (returns null if LinkedList,
empty). PriorityQueue
peek() Retrieves head without removing it. LinkedList,
PriorityQueue

Implementations of Queue:

1. LinkedList (Can act as a queue)


a. Implements both Queue and Deque.
b. Allows null elements.

Queue<Integer> queue = new LinkedList<>();


queue.offer(10);
queue.offer(20);
System.out.println(queue.poll()); // 10
System.out.println(queue.peek()); // 20

2. PriorityQueue (Elements Sorted by Priority)


a. Elements are sorted based on priority.
b. Uses a heap (default: natural ordering, but can have a custom
comparator).

Queue<Integer> priorityQueue = new PriorityQueue<>();


priorityQueue.add(30);
priorityQueue.add(10);
priorityQueue.add(20);
System.out.println(priorityQueue.poll()); // 10 (smallest first)
5. Deque Interface (Double-Ended Queue)
A Deque allows insertion and deletion from both ends.

Method Description Supported By


addFirst(E e) Adds an element at the front. ArrayDeque, LinkedList
addLast(E e) Adds an element at the end. ArrayDeque, LinkedList
removeFirst() Removes and returns the first ArrayDeque, LinkedList
element.
removeLast() Removes and returns the last ArrayDeque, LinkedList
element.

Implementations of Deque:

1. ArrayDeque (Resizable Array Implementation)


a. Faster than Stack.
b. No capacity restrictions.

Deque<String> deque = new ArrayDeque<>();


deque.addFirst("A");
deque.addLast("B");
System.out.println(deque.removeFirst()); // A

2. LinkedList (Can also be used as a deque)

6. Map Interface (Key-Value Pairs, No Duplicates in


Keys)
A Map stores key-value pairs.

Method Description Supported By


put(K key, V value) Adds a key-value pair. All Maps
get(Object key) Retrieves value for a given All Maps
key.
remove(Object key) Removes a key-value pair. All Maps
containsKey(Object key) Checks if key exists. All Maps
containsValue(Object value) Checks if value exists. All Maps
Implementations of Map:

1. HashMap (Unordered Key-Value Storage)


a. Uses a hash table.
b. Fast lookup, insertion, deletion (O(1)).
c. No order guaranteed.

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


hashMap.put(1, "One");
hashMap.put(2, "Two");
System.out.println(hashMap.get(1)); // One

2. LinkedHashMap (Maintains Insertion Order)


a. Like HashMap, but maintains insertion order.
3. TreeMap (Sorted by Key)
a. Uses a Red-Black tree.
b. Keys are sorted in natural order.
c. Slower than HashMap (O(log n)).

Map<Integer, String> treeMap = new TreeMap<>();


treeMap.put(3, "Three");
treeMap.put(1, "One");
System.out.println(treeMap); // Sorted: {1=One, 3=Three}

4. Hashtable (Thread-Safe Version of HashMap)


a. Similar to HashMap, but synchronized (thread-safe).
b. Slower due to synchronization.

Summary
1. List: Ordered, allows duplicates. (ArrayList, LinkedList, Vector, Stack)
2. Set: Unordered, no duplicates. (HashSet, LinkedHashSet, TreeSet)
3. Queue: FIFO, process elements in order. (LinkedList, PriorityQueue)
4. Deque: Allows adding/removing from both ends. (ArrayDeque, LinkedList)
5. Map: Key-value pairs, unique keys. (HashMap, LinkedHashMap, TreeMap,
Hashtable)
Allows Key
Collecti Maintain Access
Duplica Use Case Implementatio
on Type s Order Method
tes ns

Ordered collection
with possible
duplicates.
ArrayList,
Index- Suitable when
List Yes Yes LinkedList,
based precise control
Vector, Stack
over element
positions is
required.

Collection of
unique elements.
No HashSet,
Element- Ideal when
Set No (unordere LinkedHashSet,
based uniqueness is a
d) TreeSet
priority, and order
is not a concern.

First-In-First-Out
collection. Used
LinkedList,
Element- for scheduling
Queue Yes Yes (FIFO) PriorityQueue,
based tasks or handling
ArrayDeque
data in the order it
was received.

Double-Ended
Queue allowing
insertion and
Yes (both Element- removal from both ArrayDeque,
Deque Yes
ends) based ends. Useful for LinkedList
implementing
stacks and
queues.

Collection of key-
HashMap,
No value pairs. Each
No LinkedHashMa
Map (unordere Key-based key maps to a
(keys) p, TreeMap,
d) single value,
Hashtable
suitable for
associative arrays
or dictionaries.

Additional Information on Implementations:

• ArrayList:
o Allows duplicates
o Maintains insertion order
o Provides fast random access (O(1))
o Slower insertion and deletion at middle (O(n))
• LinkedList:
o Allows duplicates
o Maintains insertion order
o Faster insertion and deletion at both ends (O(1))
o Can act as both a List and a Queue or Deque
• Vector:
o Allows duplicates
o Maintains insertion order
o Synchronized (thread-safe)
o Slower performance due to synchronization overhead
• Stack:
o Extends Vector
o Follows LIFO (Last-In-First-Out) order
o Provides stack operations like push(), pop(), and peek()
• HashSet:
o Does not allow duplicates
o Does not maintain insertion order
o Offers fast lookups, insertions, and deletions (O(1))
• LinkedHashSet:
o Does not allow duplicates
o Maintains insertion order
o More efficient than TreeSet for ordered sets
• TreeSet:
o Does not allow duplicates
o Elements are sorted (natural or by comparator)
o Slower (O(log n)) due to tree-based structure
• PriorityQueue:
o Allows duplicates
o Does not maintain insertion order (elements sorted by priority)
o Often used for priority scheduling
• ArrayDeque:
o Allows duplicates
o Maintains insertion order
o Can act as both a Queue and a Deque
o More efficient than Stack
• HashMap:
o Does not allow duplicate keys (but values can be duplicated)
o Does not maintain insertion order
o Offers fast lookups, insertions, and deletions (O(1))
• LinkedHashMap:
o Does not allow duplicate keys (but values can be duplicated)
o Maintains insertion order
o Slightly slower than HashMap due to maintaining order
• TreeMap:
o Does not allow duplicate keys (but values can be duplicated)
o Keys are sorted (natural or by comparator)
o Slower (O(log n)) due to tree-based structure
• Hashtable:
o Does not allow duplicate keys (but values can be duplicated)
o Synchronized (thread-safe)
o Slower performance due to synchronization overhead

Exception Handling in Java


Exception in Java

Definition: An exception is an event that disrupts the normal flow of the program's
execution. It is an object that wraps an error or unusual condition that occurs during
program execution.

Types of Exceptions

1. Checked Exceptions:
Exceptions that must either be caught using a try-catch block or declared in the
method signature using throws. Example: IOException, SQLException. Cause:
Typically occurs due to external factors (e.g., file operations, network issues).
public void readFile(String file) throws IOException {
// Code that might throw IOException
}

2. Unchecked Exceptions (Runtime Exceptions):


Exceptions that are not required to be caught or declared. These are usually
caused by programming errors. Example: NullPointerException,
ArithmeticException, ArrayIndexOutOfBoundsException. Cause: Caused by
bugs or logical errors in the code.

int result = 10 / 0; // Throws ArithmeticException

3. Errors:
Serious problems that usually cannot be handled by the program (e.g., JVM or
system failures). Example: OutOfMemoryError, StackOverflowError. Cause:
System-level failures beyond the program's control.

Key Differences Between Error and Exception

Catego Error Exception


ry
Definiti Serious system-level failure. Problems that can be handled or
on fixed.
Examp OutOfMemoryError, IOException,
les StackOverflowError NullPointerException
Handli Cannot be handled. Can be handled using try-catch.
ng
Cause System-related issues (e.g., Application issues (e.g., logic
hardware). bugs).

• Checked Exceptions: Must be handled or declared (IOException,


SQLException).
• Unchecked Exceptions: Not required to be handled (NullPointerException,
ArithmeticException).
• Errors: Serious issues (e.g., OutOfMemoryError, StackOverflowError).
Keywords for handling Exception on Java

1. try-catch

• Purpose: Handles exceptions that occur within the try block.


• Use Case: Used to catch and handle errors, preventing crashes.
• Example:

try {
int result = 10 / 0; // ArithmeticException
} catch (ArithmeticException e) {
System.out.println("Cannot divide by zero!");
}

2. finally

• Purpose: Executes cleanup code after try-catch, regardless of whether an


exception occurred.
• Use Case: Used for releasing resources, e.g., closing files.
• Example:

try {
FileReader fr = new FileReader("file.txt");
} catch (IOException e) {
System.out.println("File not found!");
} finally {
fr.close(); // Always executed
}

3. throw

• Purpose: Manually throws an exception.


• Use Case: Used when you want to explicitly trigger an exception in code.
• Example:

public void checkAge(int age) {


if (age < 18) {
throw new IllegalArgumentException("Age must be 18 or older!");
}
}

4. throws

• Purpose: Declares that a method might throw exceptions.


• Use Case: Used when a method can throw a checked exception, and the caller
must handle it.
• Example:

public void readFile(String file) throws IOException {


// Code that may throw IOException
}

Summary Table:

Keyword Purpose Use Case


try-catch Handle exceptions within try Catch errors to prevent crashing.
block.
finally Execute cleanup code after Release resources (e.g., close files, DB
try-catch. connections).
throw Manually trigger an Explicitly raise an exception in code.
exception.
throws Declare possible exceptions Inform callers to handle exceptions.
in method signature.

Java I/O Streams


Java I/O (Input/Output) provides an interface for reading from and writing to files,
network connections, memory, and other I/O sources. The Java I/O API is built on
streams that are divided into two categories: Byte Streams and Character Streams.

File Handling in Java

File handling refers to the ability to manipulate files: create, delete, read, write, and
modify them. Java provides the File class to perform these tasks.

• File Class:
o The File class represents a file or directory path.
o It provides methods like createNewFile(), delete(), exists(), renameTo(),
and more to work with files and directories.

Basic File Operations:

1. Create a File:
a. createNewFile() method is used to create a new empty file.
b. If the file already exists, this method returns false.

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

public class FileHandlingExample {


public static void main(String[] args) throws IOException {
File file = new File("example.txt");

if (file.createNewFile()) {
System.out.println("File created: " + file.getName());
} else {
System.out.println("File already exists.");
}
}
}

2. Delete a File:
a. delete() method is used to delete a file or directory.

File file = new File("example.txt");


if (file.delete()) {
System.out.println("Deleted the file: " + file.getName());
} else {
System.out.println("Failed to delete the file.");
}

3. Check if File Exists:


a. exists() method checks whether a file or directory exists.

if (file.exists()) {
System.out.println("File exists.");
} else {
System.out.println("File does not exist.");
}

What is a Stream?

• A stream is a sequence of data that can be read from or written to.


• Streams handle data in a linear flow and are classified into two types:
o Byte Stream (for raw binary data)
o Character Stream (for text data)

Types of Streams

1. Byte Streams:
a. Byte streams handle I/O of raw binary data (8 bits).
b. They are used for all kinds of I/O, such as image, video, and audio files,
and work with binary files.
c. Classes in Byte Streams:
i. FileInputStream (for reading binary data)
ii. FileOutputStream (for writing binary data)

Example (Reading and Writing binary data):

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class ByteStreamExample {


public static void main(String[] args) throws IOException {
FileInputStream input = new FileInputStream("input.txt");
FileOutputStream output = new FileOutputStream("output.txt");

int data;
while ((data = input.read()) != -1) {
output.write(data);
}

input.close();
output.close();
}
}

2. Character Streams:
a. Character streams handle I/O of character data (16 bits). They are
specifically designed for handling text data.
b. Classes in Character Streams:
i. FileReader (for reading character data)
ii. FileWriter (for writing character data)

Example (Reading and Writing text data):

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

public class CharStreamExample {


public static void main(String[] args) throws IOException {
FileReader reader = new FileReader("input.txt");
FileWriter writer = new FileWriter("output.txt");

int character;
while ((character = reader.read()) != -1) {
writer.write(character);
}
reader.close();
writer.close();
}
}

Buffered Streams

Buffered streams improve I/O performance by reading or writing data in larger chunks,
minimizing the number of I/O operations.

• BufferedReader (Character Stream): Reads data efficiently using a buffer.


• BufferedWriter (Character Stream): Writes data efficiently using a buffer.
• BufferedInputStream (Byte Stream): Provides buffered byte-based input.
• BufferedOutputStream (Byte Stream): Provides buffered byte-based output.

Example (Buffered Stream for File Reading and Writing):


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

public class BufferedStreamExample {


public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new FileReader("input.txt"));
BufferedWriter writer = new BufferedWriter(new FileWriter("output.txt"));

String line;
while ((line = reader.readLine()) != null) {
writer.write(line);
writer.newLine(); // To add new line after each line
}

reader.close();
writer.close();
}
}

• Explanation: This example reads a file line by line using BufferedReader and
writes each line to a new file using BufferedWriter.

Serialization and Deserialization

• Serialization: The process of converting an object into a byte stream to save it to


a file or send it over a network.
• Deserialization: The reverse process of converting byte stream back into an
object.

Serializable Interface: The Serializable interface must be implemented by any class


whose object you want to serialize.

Example:

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

class Person implements Serializable {


String name;
int age;

Person(String name, int age) {


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

public class SerializationExample {


public static void main(String[] args) throws IOException, ClassNotFoundException {
// Serialize
Person person = new Person("John", 25);
ObjectOutputStream out = new ObjectOutputStream(new
FileOutputStream("person.ser"));
out.writeObject(person);
out.close();

// Deserialize
ObjectInputStream in = new ObjectInputStream(new
FileInputStream("person.ser"));
Person deserializedPerson = (Person) in.readObject();
System.out.println(deserializedPerson.name + " " + deserializedPerson.age);
in.close();
}
}

• Explanation: The Person object is serialized to a file and then deserialized back
into an object.
File Handling in Detail:

File handling is essential in any programming language, and Java provides easy-to-use
classes for managing files. These operations include reading, writing, creating, deleting,
renaming, and modifying files.

File Class Methods:

• createNewFile(): Creates a new file.


• exists(): Checks if a file exists.
• delete(): Deletes the file.
• renameTo(File dest): Renames the file.
• getAbsolutePath(): Returns the absolute path of the file.
• length(): Returns the size of the file in bytes.

Example:

import java.io.File;

public class FileOperations {


public static void main(String[] args) {
File file = new File("example.txt");

// Check if file exists


if (file.exists()) {
System.out.println("File exists: " + file.getName());
System.out.println("File size: " + file.length() + " bytes");
} else {
System.out.println("File does not exist.");
}
}
}

Summary:

• Byte Streams work with raw binary data.


• Character Streams are for text-based I/O.
• Buffered Streams improve performance by reading/writing large chunks of data.
• Serialization allows saving and restoring Java objects.
• File Handling in Java is flexible with the File class and various I/O stream
classes.

These I/O mechanisms make Java a powerful tool for working with files, networks, and
other forms of input/output.

Java Beans:
Java Beans are classes in Java that follow a specific convention. They are used to
encapsulate multiple objects into a single object (a bean). The main purpose of Java
Beans is to represent data in a consistent way and allow easy manipulation of that data.

Java Beans are typically used in Enterprise Applications, GUI Development, and for
Data Transfer Objects (DTOs) in applications. They simplify the management of
complex data in Java applications.

What is a Java Bean?

A Java Bean is a reusable software component that follows these conventions:

1. Public Constructor: A Java Bean must have a no-argument public constructor.


2. Private Member Variables: The fields (properties) of a Java Bean are private,
meaning they cannot be accessed directly from outside the class.
3. Getters and Setters: Java Beans use getter and setter methods to access and
update the properties. These methods follow specific naming conventions
(getProperty() and setProperty()).
4. Serializable: A Java Bean should implement the Serializable interface to allow
its state to be saved and restored.

Why Java Beans are Used?

1. Encapsulation: Java Beans encapsulate data in a clean, standardized way. Each


property is private and can only be accessed or modified via getter and setter
methods.
2. Reusability: Since Java Beans are standardized, they can be reused across
different parts of an application or even in different projects.
3. Data Handling: Java Beans are used for transferring data between layers, such
as from the database to the presentation layer.
4. Compatibility: Beans work well with frameworks like Spring, Java EE, and
JavaFX for building web and GUI applications.

Key Features of Java Beans:

• Private Properties: Fields are encapsulated as private variables.


• Public Getter and Setter Methods: These methods provide access to the
private properties.
• Public No-Argument Constructor: Ensures that Java Beans can be easily
instantiated.
• Serializable: Implements java.io.Serializable to allow serialization and
deserialization of the bean’s state.

Example of a Simple Java Bean

Here’s a simple example of a Java Bean that represents a Person:

import java.io.Serializable;

public class Person implements Serializable {


private String name;
private int age;

// Public no-argument constructor


public Person() {
}

// Getter for name


public String getName() {
return name;
}

// Setter for name


public void setName(String name) {
this.name = name;
}
// Getter for age
public int getAge() {
return age;
}

// Setter for age


public void setAge(int age) {
this.age = age;
}

// Method to display person info


public void displayInfo() {
System.out.println("Name: " + name + ", Age: " + age);
}

public static void main(String[] args) {


// Create a new Person object using the no-argument constructor
Person person = new Person();
// Set values using setter methods
person.setName("Alice");
person.setAge(25);
// Access data using getter methods
person.displayInfo(); // Output: Name: Alice, Age: 25
}
}

Explanation:

• Private Fields: name and age are private variables.


• Getter and Setter Methods: We have getName() and setName(), as well as
getAge() and setAge().
• Serializable: The class implements Serializable, allowing its objects to be easily
converted into a byte stream for storage or transfer.
• Constructor: A no-argument constructor is provided to make it a valid Java
Bean.
When to Use Java Beans:

• Data Transfer: When you need to transfer data between layers in a software
application, like from a database to a web page.
• Encapsulation: To ensure that data is accessed and modified in a controlled
manner using getters and setters.
• Framework Integration: Many Java frameworks, like Spring, rely on Java Beans
for configuration and data binding.

Summary:

• Java Beans are reusable software components that follow certain conventions
(e.g., private fields, public no-argument constructor, getter and setter methods).
• Used for: Encapsulating data, transferring data between layers, or simplifying
data manipulation.
• Example: A class representing a Person with properties like name and age,
which can be accessed and modified through getter and setter methods.

Multithreading & Multitasking in Java – High-


Level Overview
Understanding Key Concepts

Before diving into Java multithreading, let's understand some fundamental concepts:

Term Description
Processo The hardware that executes instructions. Modern CPUs have multiple
r (CPU) cores.
Process An executing instance of a program. Each process runs independently
with its own memory.
Thread A lightweight process that runs inside a program (process). Multiple
threads share the same memory.
Multipro Running multiple processes simultaneously. Each process has its own
cessing memory space.
Multithre Running multiple threads within a single process, sharing the same
ading memory but executing tasks independently.
1. What is Multitasking?
Multitasking is the ability of an operating system to run multiple tasks (processes or
threads) simultaneously to improve efficiency.

Types of Multitasking

Type Description
Process-Based Running multiple processes simultaneously. Each process has
Multitasking separate memory.
Thread-Based Running multiple threads within a single process. Threads
Multitasking share the same memory space.

Process-Based Multitasking

• Each process runs independently.


• Context switching between processes is heavy.
• Example: Running a browser and a music player at the same time.

Thread-Based Multitasking

• A single process has multiple threads.


• Threads share resources, making context switching lightweight.
• Example: A text editor where one thread handles typing while another checks for
spelling errors.

2. What is a Thread?
A thread is the smallest unit of execution in a program. Multiple threads can run in
parallel to perform tasks more efficiently.

Types of Threads

Type Description
User Created and controlled by the programmer.
Thread
Daemon Background threads (e.g., Garbage Collector). Automatically stops when
Thread all user threads finish execution.
Main Thread in Java

Every Java program has a main thread, which runs the main() method.

Example:

class MainThreadExample {
public static void main(String[] args) {
Thread t = Thread.currentThread(); // Getting main thread
System.out.println("Current Thread: " + t.getName());
}
}

Output:

Current Thread: main

3. Creating Threads in Java


Java provides two ways to create a thread:

1. Extending the Thread Class

class MyThread extends Thread {


public void run() { // Overriding run() method
System.out.println("Thread is running...");
}

public static void main(String[] args) {


MyThread t = new MyThread();
t.start(); // Starts a new thread
}
}
2. Implementing the Runnable Interface

class MyRunnable implements Runnable {


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

public static void main(String[] args) {


Thread t = new Thread(new MyRunnable());
t.start();
}
}

Runnable vs Thread Class

Feature Thread Class Runnable Interface


Inheritance Cannot extend another Can implement multiple
class interfaces
Resource Not efficient Recommended for better
Sharing efficiency

4. Thread Lifecycle
State Description
New Thread is created but not started.
Runnable Thread is ready and waiting for CPU time.
Running Thread is executing.
Blocked Waiting for a resource to be free.
Waiting Waiting indefinitely for another thread's
signal.
Timed Waiting Waiting for a specific time (e.g., sleep()).
Terminated Thread has finished execution.

5. Thread Synchronization
When multiple threads access shared resources, race conditions may occur. Java
provides synchronized to prevent this.
class Counter {
private int count = 0;

public synchronized void increment() {


count++;
}

public int getCount() {


return count;
}
}

Thread Synchronization Methods

Synchronization Type Description


Synchronized The entire method is locked for one thread at a
Method time.
Synchronized Block A specific block of code is locked.
Lock Interface Provides more flexibility than synchronized.

6. Deadlock in Java
A deadlock occurs when two threads wait for each other's resources, causing a cycle.

Example of Deadlock

class Deadlock {
static final Object lock1 = new Object();
static final Object lock2 = new Object();

public static void main(String[] args) {


Thread t1 = new Thread(() -> {
synchronized (lock1) {
System.out.println("Thread 1 locked lock1");
try { Thread.sleep(100); } catch (Exception e) {}
synchronized (lock2) {
System.out.println("Thread 1 locked lock2");
}
}
});

Thread t2 = new Thread(() -> {


synchronized (lock2) {
System.out.println("Thread 2 locked lock2");
try { Thread.sleep(100); } catch (Exception e) {}
synchronized (lock1) {
System.out.println("Thread 2 locked lock1");
}
}
});

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

How to Avoid Deadlock?

• Avoid nested locks.


• Use lock ordering.
• Use tryLock() with a timeout.

7. Inter-Thread Communication
Java provides wait(), notify(), and notifyAll() to coordinate threads.

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

public synchronized void put(int num) {


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

public synchronized int get() {


while (!available) {
try { wait(); } catch (InterruptedException e) {}
}
available = false;
System.out.println("Consumed: " + value);
notify();
return value;
}
}

class Producer extends Thread {


SharedResource resource;

Producer(SharedResource res) {
this.resource = res;
}

public void run() {


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

class Consumer extends Thread {


SharedResource resource;

Consumer(SharedResource res) {
this.resource = res;
}

public void run() {


for (int i = 1; i <= 5; i++) {
resource.get();
}
}
}
public class InterThreadExample {
public static void main(String[] args) {
SharedResource res = new SharedResource();
new Producer(res).start();
new Consumer(res).start();
}
}

8. Summary Table
Concept Description
Multitasking Running multiple tasks simultaneously.
Process-Based Multiple independent processes executing.
Multitasking
Thread-Based Multiple threads running within the same process.
Multitasking
Main Thread Default thread that runs main().
Creating Threads Extend Thread class or implement Runnable.
Thread Lifecycle New → Runnable → Running → Waiting/Blocked →
Terminated.
Synchronization Prevents race conditions using synchronized.
Deadlock Two or more threads waiting indefinitely for each other’s
resources.
Inter-Thread Uses wait(), notify(), and notifyAll().
Communication

Summary
• Multithreading improves performance but must be managed carefully.
• Synchronization prevents data corruption, but excessive locking can reduce
performance.
• Deadlocks should be avoided using proper resource management.

An Example:
class NumberPrinter extends Thread {
private int start, end;

public NumberPrinter(int start, int end) {

this.start = start;

this.end = end;

public void run() {

for (int i = start; i <= end; i++) {

System.out.println(Thread.currentThread().getName() + " -> " + i);

try {

Thread.sleep(500); // Adding sleep for better readability

} catch (InterruptedException e) {

System.out.println(e.getMessage());

public static void main(String[] args) {

Thread t1 = new NumberPrinter(1, 10); // Thread 1 prints 1 to 10

Thread t2 = new NumberPrinter(11, 20); // Thread 2 prints 11 to 20

t1.start();

t2.start();
}

Java GUI Development with Swing


1. Introduction to Java GUI

What is GUI?

A Graphical User Interface (GUI) allows users to interact with programs using
graphical components such as buttons, text fields, menus, and dialogs instead of
command-line interfaces.

Why Swing?

Java provides two primary GUI frameworks:

Framework Description
AWT (Abstract Window Uses native OS components (Heavyweight, limited
Toolkit) features).
Swing Fully Java-based, lightweight, flexible, and rich in UI
components.

Advantages of Swing:

Cross-platform compatibility

Lightweight components

More customizable than AWT

MVC-based architecture (Model-View-Controller)

2. Components & Containers


Swing provides various components (UI elements) and containers (holders for
components).
2.1 Containers

Containers hold other components and define the structure of the UI.

Container Description
JFrame The main application window.
JPanel A sub-container that groups components.
JDialog A popup dialog box.
JApplet A container for embedding applets in web
pages.
JWindow A borderless, undecorated window.

Example: Creating a JFrame

import javax.swing.*;

public class SimpleFrame {


public static void main(String[] args) {
JFrame frame = new JFrame("My First GUI");
frame.setSize(400, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}

2.2 Swing Components

Component Description
JLabel Displays static text or images.
JTextField Single-line text input.
JButton Clickable button.
JTextArea Multi-line text input.
JCheckBox Checkbox (on/off selection).
JRadioButton Used in groups for mutually exclusive
choices.
JComboBox Dropdown selection menu.
JList List of selectable items.
JMenuBar, JMenu, JMenuItem Menus and menu items.
Example: Adding Components to JFrame

import javax.swing.*;

public class ComponentsExample {


public static void main(String[] args) {
JFrame frame = new JFrame("Swing Components");
frame.setSize(400, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

JPanel panel = new JPanel();

JLabel label = new JLabel("Enter Name:");


JTextField textField = new JTextField(15);
JButton button = new JButton("Submit");

panel.add(label);
panel.add(textField);
panel.add(button);

frame.add(panel);
frame.setVisible(true);
}
}

3. Layout Managers
Swing provides Layout Managers to arrange components in a container.

Here’s a detailed explanation of each Layout Manager in Swing, along with examples:

1. FlowLayout
Description:

• Default layout for JPanel


• Arranges components in a row from left to right
• Wraps to the next line when space runs out
• Supports alignment (LEFT, CENTER, RIGHT) and horizontal & vertical gaps

Example:

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

public class FlowLayoutExample {


public static void main(String[] args) {
JFrame frame = new JFrame("FlowLayout Example");
frame.setSize(400, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

JPanel panel = new JPanel();


panel.setLayout(new FlowLayout(FlowLayout.CENTER, 10, 10)); // Center aligned
with gaps

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


panel.add(new JButton("Button 2"));
panel.add(new JButton("Button 3"));
panel.add(new JButton("Button 4"));

frame.add(panel);
frame.setVisible(true);
}
}

2. BorderLayout
Description:

• Divides the container into 5 regions:


o NORTH (Top)
o SOUTH (Bottom)
o EAST (Right)
o WEST (Left)
o CENTER (Middle)
• Each region can hold only one component (use JPanel for multiple
components)
• Components in NORTH and SOUTH expand horizontally
• Components in EAST and WEST expand vertically
• CENTER takes up remaining space

Example:

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

public class BorderLayoutExample {


public static void main(String[] args) {
JFrame frame = new JFrame("BorderLayout Example");
frame.setSize(400, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
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.setVisible(true);
}
}

3. GridLayout
Description:

• Arranges components in a grid of equal-sized cells


• Each row and column gets equal space
• Components are placed left to right, top to bottom
• Can specify number of rows and columns (GridLayout(rows, cols))
• Spacing (gaps) between cells can be defined

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

public class GridLayoutExample {


public static void main(String[] args) {
JFrame frame = new JFrame("GridLayout Example");
frame.setSize(400, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.setLayout(new GridLayout(2, 3, 10, 10)); // 2 rows, 3 columns, 10px


horizontal gap, 10px vertical gap

frame.add(new JButton("1"));
frame.add(new JButton("2"));
frame.add(new JButton("3"));
frame.add(new JButton("4"));
frame.add(new JButton("5"));
frame.add(new JButton("6"));

frame.setVisible(true);
}
}

4. BoxLayout
Description:

• Arranges components in a single row or column


• More flexible than FlowLayout
• Components don’t resize automatically
• Uses Box.createRigidArea() to create spacing

Example (Vertical BoxLayout):

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

public class BoxLayoutExample {


public static void main(String[] args) {
JFrame frame = new JFrame("BoxLayout Example");
frame.setSize(300, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

JPanel panel = new JPanel();


panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); // Vertical layout

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


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

frame.add(panel);
frame.setVisible(true);
}
}

5. CardLayout
Description:

• Used to switch between different panels (like a tabbed interface or wizard)


• Only one panel is visible at a time
• Allows easy navigation between multiple views
• Uses show() method to switch panels

Example:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class CardLayoutExample {


public static void main(String[] args) {
JFrame frame = new JFrame("CardLayout Example");
frame.setSize(400, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel cardPanel = new JPanel();
CardLayout cardLayout = new CardLayout();
cardPanel.setLayout(cardLayout);

JPanel panel1 = new JPanel();


panel1.add(new JLabel("Panel 1"));
panel1.setBackground(Color.CYAN);

JPanel panel2 = new JPanel();


panel2.add(new JLabel("Panel 2"));
panel2.setBackground(Color.ORANGE);

cardPanel.add(panel1, "Card1");
cardPanel.add(panel2, "Card2");

JButton nextButton = new JButton("Next");


nextButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
cardLayout.next(cardPanel);
}
});

frame.add(cardPanel, BorderLayout.CENTER);
frame.add(nextButton, BorderLayout.SOUTH);
frame.setVisible(true);
}
}

Summary
Layout Description
Manager
FlowLayout Arranges components in a row, wraps if space runs out.
BorderLayou Divides the container into 5 regions (NORTH, SOUTH, EAST, WEST,
t CENTER).
GridLayout Arranges components in a grid of equal-sized cells.
BoxLayout Arranges components in a single row or column.
CardLayout Allows flipping between different panels (useful for wizards).
4. Event Handling in Swing
Swing uses Event Listeners to handle user actions.

Listener Description
Interface
ActionListener Handles button clicks.
MouseListener Detects mouse clicks and movements.
KeyListener Captures keyboard input.
WindowListener Handles window events (open, close, minimize,
etc.).

Example: Handling Button Click

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

public class ButtonClickExample {


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

button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(null, "Button Clicked!");
}
});

frame.add(button);
frame.setSize(300, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
5. Dialogs in Swing
Swing provides JOptionPane and JDialog for pop-up messages.

5.1 JOptionPane (Predefined Dialogs)

Dialog Type Method


Message Dialog showMessageDialog()
Confirmation Dialog showConfirmDialog()
Input Dialog showInputDialog()
Option Dialog showOptionDialog()

Example: Message Dialog

JOptionPane.showMessageDialog(null, "This is a message dialog!", "Title",


JOptionPane.INFORMATION_MESSAGE);

6. Full Project: Student Registration Form


import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class StudentForm {


public static void main(String[] args) {
JFrame frame = new JFrame("Student Registration Form");
frame.setSize(400, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

JPanel panel = new JPanel();


panel.setLayout(new GridLayout(5, 2));

JLabel nameLabel = new JLabel("Name:");


JTextField nameField = new JTextField(15);
JLabel ageLabel = new JLabel("Age:");
JTextField ageField = new JTextField(3);
JLabel genderLabel = new JLabel("Gender:");
JComboBox<String> genderBox = new JComboBox<>(new String[]{"Male", "Female",
"Other"});
JButton submitButton = new JButton("Submit");

panel.add(nameLabel);
panel.add(nameField);
panel.add(ageLabel);
panel.add(ageField);
panel.add(genderLabel);
panel.add(genderBox);
panel.add(submitButton);

frame.add(panel);
frame.setVisible(true);

submitButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String name = nameField.getText();
String age = ageField.getText();
String gender = (String) genderBox.getSelectedItem();
JOptionPane.showMessageDialog(frame, "Student Info:\nName: " + name +
"\nAge: " + age + "\nGender: " + gender);
}
});
}
}

Conclusion

Swing provides powerful GUI components for Java applications.

Layouts help arrange UI elements effectively.

Event listeners enable user interaction.

Dialogs provide pop-ups for user messages and confirmations.


Graphics in Java (Using the Graphics
Class)
Java provides the Graphics class to create 2D graphics, such as lines, shapes, text,
and images. The Graphics class belongs to the java.awt package and is primarily used
in GUI applications to render custom graphics.

1. What is the Graphics Class?


The Graphics class is an abstract class that provides methods to draw shapes, text,
and images onto components like JPanel, Canvas, or JFrame.

It acts as a drawing surface for customizing the appearance of GUI applications.

Key Features of the Graphics Class:

• Supports drawing shapes (lines, rectangles, ovals, arcs, polygons).


• Enables drawing text with different fonts and styles.
• Supports color management using the Color class.
• Allows image rendering.
• Provides methods for clipping (restricting the drawing area).

2. How to Use the Graphics Class in Java?


To use the Graphics class, override the paintComponent(Graphics g) method of JPanel
or paint(Graphics g) of Canvas.

Steps to use Graphics in Java:

1. Create a JFrame as the main window.


2. Create a custom class that extends JPanel or Canvas.
3. Override the paintComponent(Graphics g) method.
4. Use the Graphics object (g) to draw shapes, text, or images.
5. Add the custom panel to the frame and display the GUI.
3. Drawing Shapes Using Graphics
The Graphics class provides methods to draw different shapes.

Here’s a table of commonly used shape-drawing methods:

Method Description
drawLine(x1, y1, x2, y2) Draws a straight line from (x1, y1) to
(x2, y2).
drawRect(x, y, width, height) Draws a rectangle outline.
fillRect(x, y, width, height) Draws a filled rectangle.
drawOval(x, y, width, height) Draws an oval inside the given
rectangle.
fillOval(x, y, width, height) Draws a filled oval.
drawArc(x, y, width, height, startAngle, Draws an arc within an oval.
arcAngle)
fillArc(x, y, width, height, startAngle, arcAngle) Draws a filled arc.
drawPolygon(int[] xPoints, int[] yPoints, int n) Draws a polygon using an array of x
and y points.
fillPolygon(int[] xPoints, int[] yPoints, int n) Draws a filled polygon.

4. Example: Drawing Basic Shapes


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

public class GraphicsDemo extends JPanel {


public GraphicsDemo() {
JFrame frame = new JFrame("Graphics in Java");
frame.setSize(400, 600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(this);
frame.setVisible(true);
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);

g.setColor(Color.RED);
g.drawLine(20, 50, 200, 50);
g.drawRect(50, 80, 150, 100);
g.fillRect(220, 80, 150, 100);
g.drawOval(50, 200, 150, 100);
g.fillOval(220, 200, 150, 100);
g.drawArc(50, 320, 150, 100, 0, 180);
g.fillArc(220, 320, 150, 100, 0, 180);

int[] xPoints = {100, 150, 50};


int[] yPoints = {450, 500, 500};
g.drawPolygon(xPoints, yPoints, 3);
}

public static void main(String[] args) {


new GraphicsDemo();
}
}

5. Drawing Text Using Graphics


Use the drawString() method to display text on the panel.

Example: Drawing Text

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

public class TextGraphics extends JPanel {


public TextGraphics() {
JFrame frame = new JFrame("Text in Graphics");
frame.setSize(400, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(this);
frame.setVisible(true);
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setFont(new Font("Arial", Font.BOLD, 20));
g.setColor(Color.BLUE);
g.drawString("Hello, Java Graphics!", 50, 50);
}

public static void main(String[] args) {


new TextGraphics();
}
}

6. Loading and Drawing Images


To display an image, use drawImage().

Example: Displaying an Image

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

public class ImageGraphics extends JPanel {


private Image image;

public ImageGraphics() {
image = new ImageIcon("image.jpg").getImage();

JFrame frame = new JFrame("Image in Graphics");


frame.setSize(500, 500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(this);
frame.setVisible(true);
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 50, 50, this);
}
public static void main(String[] args) {
new ImageGraphics();
}
}

7. Color and Font Handling


• Changing Colors: Use g.setColor(Color.RED).
• Setting Fonts: Use g.setFont(new Font("Arial", Font.BOLD, 20)).

Example:

g.setColor(Color.GREEN);
g.fillRect(50, 50, 100, 50);

g.setFont(new Font("Courier New", Font.ITALIC, 25));


g.drawString("Colored Text", 50, 150);

8. Double Buffering (Smooth Graphics)


Graphics rendering may flicker in animations. To prevent this, double buffering is used.
Use BufferedImage instead of directly using Graphics.

Summary
• Graphics in Java allow custom drawing of shapes, text, and images.
• Graphics is used inside paintComponent(Graphics g).
• Swing components (JPanel, JFrame) provide the drawing surface.

You might also like