0% found this document useful (0 votes)
7 views39 pages

UNIT - V - STRING HANDLING IN JAVA UPDATED

The document provides an overview of string handling in Java, detailing the String class and its methods, as well as the CharSequence interface. It also covers the StringBuffer class for mutable strings, basic string operations, and multithreading concepts including thread creation, states, priorities, and synchronization. Additionally, it discusses potential issues like deadlocks and race conditions, along with inter-thread communication methods.

Uploaded by

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

UNIT - V - STRING HANDLING IN JAVA UPDATED

The document provides an overview of string handling in Java, detailing the String class and its methods, as well as the CharSequence interface. It also covers the StringBuffer class for mutable strings, basic string operations, and multithreading concepts including thread creation, states, priorities, and synchronization. Additionally, it discusses potential issues like deadlocks and race conditions, along with inter-thread communication methods.

Uploaded by

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

UNIT – V

STRING HANDLING
String Handling in Java

Introduction to String Handling

Strings in Java are objects that represent sequences of characters. The String class in Java is used
to create and manipulate strings. Strings are immutable, meaning once a string is created, it
cannot be changed. Various methods are provided by the String class for string manipulation.

Interface CharSequence

The CharSequence interface represents a readable sequence of char values. It is the parent interface
for several classes, including String, StringBuffer, and StringBuilder.

Key Methods:

 char charAt(int index): Returns the character at the specified index.


 int length(): Returns the length of the sequence.

 CharSequence subSequence(int start, int end): Returns a new CharSequence that is a subsequence
of this sequence.
 String toString(): Returns a String containing the characters in this sequence.

Class String

The String class implements the CharSequence interface and represents a sequence of characters.

Creating Strings:

 Using string literals:

java
Copy code
String str1 = "Hello, World!";
 Using the new keyword:

java
Copy code
String str2 = new String("Hello, World!");

Key Methods of String Class:


 int length(): Returns the length of the string.
 char charAt(int index): Returns the character at the specified index.
 String substring(int beginIndex): Returns a substring starting from beginIndex to the end.
 String substring(int beginIndex, int endIndex): Returns a substring from beginIndex to endIndex - 1.
 boolean contains(CharSequence s): Checks if the string contains the specified sequence of
characters.
 boolean equals(Object obj): Compares the string to the specified object.
 boolean equalsIgnoreCase(String anotherString): Compares the string to another string, ignoring
case considerations.
 int compareTo(String anotherString): Compares two strings lexicographically.
 String toLowerCase(): Converts all characters of the string to lower case.
 String toUpperCase(): Converts all characters of the string to upper case.
 String trim(): Removes leading and trailing whitespace.
 String replace(CharSequence target, CharSequence replacement) :
Replaces each substring of the
string that matches the target sequence with the specified replacement sequence.
 String[] split(String regex): Splits the string around matches of the given regular expression.

Example Code

Basic String Operations

java
Copy code
public class StringExample {
public static void main(String[] args) {
// Creating strings
String str1 = "Hello, World!";
String str2 = new String("Java Programming");

// String length
System.out.println("Length of str1: " + str1.length());

// Character at a specific index


System.out.println("Character at index 7 in str1: " + str1.charAt(7));

// Substring
System.out.println("Substring from index 7 in str1: " + str1.substring(7));
System.out.println("Substring from index 7 to 12 in str1: " + str1.substring(7, 12));

// Checking if a string contains a sequence


System.out.println("str1 contains 'World': " + str1.contains("World"));
// String comparison
System.out.println("str1 equals 'Hello, World!': " + str1.equals("Hello, World!"));
System.out.println("str1 equalsIgnoreCase 'hello, world!': " + str1.equalsIgnoreCase("hello, world!"));

// String case conversion


System.out.println("str1 to lower case: " + str1.toLowerCase());
System.out.println("str1 to upper case: " + str1.toUpperCase());

// Trimming whitespace
String str3 = " Hello, World! ";
System.out.println("str3 after trim: '" + str3.trim() + "'");

// Replacing characters
System.out.println("str1 after replacing 'World' with 'Java': " + str1.replace("World", "Java"));

// Splitting strings
String str4 = "apple,banana,cherry";
String[] fruits = str4.split(",");
for (String fruit : fruits) {
System.out.println(fruit);
}
}
}

Extracting Characters from Strings

Java provides several methods in the String class to extract characters or substrings from a string.

1. charAt(int index)

Returns the character at the specified index.

java
Copy code
public class Main {
public static void main(String[] args) {
String str = "Hello, World!";
char ch = str.charAt(0);
System.out.println("Character at index 0: " + ch); // Output: H
}
}

2. substring(int beginIndex)

Returns a new string that is a substring of the original string, starting from the specified index.

java
Copy code
public class Main {
public static void main(String[] args) {
String str = "Hello, World!";
String substr = str.substring(7);
System.out.println("Substring from index 7: " + substr); // Output: World!
}
}

3. substring(int beginIndex, int endIndex)

Returns a new string that is a substring of the original string, starting from beginIndex and ending
at endIndex (exclusive).

java
Copy code
public class Main {
public static void main(String[] args) {
String str = "Hello, World!";
String substr = str.substring(7, 12);
System.out.println("Substring from index 7 to 11: " + substr); // Output: World
}
}

4. toCharArray()

Converts the entire string into a new character array.

java
Copy code
public class Main {
public static void main(String[] args) {
String str = "Hello, World!";
char[] charArray = str.toCharArray();
System.out.println("Character array: " + Arrays.toString(charArray)); // Output: [H, e, l, l, o, ,, , W, o, r, l, d, !]
}
}

5. getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)

Copies characters from the string into the destination character array.

java
Copy code
public class Main {
public static void main(String[] args) {
String str = "Hello, World!";
char[] dst = new char[5];
str.getChars(7, 12, dst, 0);
System.out.println("Destination array: " + Arrays.toString(dst)); // Output: [W, o, r, l, d]
}
}
Comparing Strings

Java provides several methods to compare strings.

1. equals(Object obj)

Compares the string to the specified object. Returns true if the object is a string with the same
sequence of characters.

java
Copy code
public class Main {
public static void main(String[] args) {
String str1 = "Hello";
String str2 = "Hello";
String str3 = "World";
System.out.println(str1.equals(str2)); // Output: true
System.out.println(str1.equals(str3)); // Output: false
}
}

2. equalsIgnoreCase(String anotherString)

Compares the string to another string, ignoring case considerations.

java
Copy code
public class Main {
public static void main(String[] args) {
String str1 = "Hello";
String str2 = "hello";
System.out.println(str1.equalsIgnoreCase(str2)); // Output: true
}
}

3. compareTo(String anotherString)

Compares two strings lexicographically. Returns a negative integer, zero, or a positive integer if
the string is less than, equal to, or greater than the specified string.

java
Copy code
public class Main {
public static void main(String[] args) {
String str1 = "Hello";
String str2 = "World";
String str3 = "Hello";
System.out.println(str1.compareTo(str2)); // Output: negative value (because "Hello" is lexicographically less
than "World")
System.out.println(str1.compareTo(str3)); // Output: 0 (because "Hello" is equal to "Hello")
}
}

4. compareToIgnoreCase(String str)

Compares two strings lexicographically, ignoring case considerations.

java
Copy code
public class Main {
public static void main(String[] args) {
String str1 = "Hello";
String str2 = "hello";
System.out.println(str1.compareToIgnoreCase(str2)); // Output: 0 (because "Hello" is equal to "hello" ignoring
case)
}
}

5. regionMatches(int toffset, String other, int ooffset, int len)

Tests if two string regions are equal.

java
Copy code
public class Main {
public static void main(String[] args) {
String str1 = "Hello, World!";
String str2 = "World";
boolean match = str1.regionMatches(7, str2, 0, 5);
System.out.println("Region matches: " + match); // Output: true
}
}

6. startsWith(String prefix)

Tests if the string starts with the specified prefix.

java
Copy code
public class Main {
public static void main(String[] args) {
String str = "Hello, World!";
System.out.println(str.startsWith("Hello")); // Output: true
System.out.println(str.startsWith("World")); // Output: false
}
}

7. endsWith(String suffix)

Tests if the string ends with the specified suffix.

java
Copy code
public class Main {
public static void main(String[] args) {
String str = "Hello, World!";
System.out.println(str.endsWith("World!")); // Output: true
System.out.println(str.endsWith("Hello")); // Output: false
}
}

Modifying and Searching: Class StringBuffer

The StringBuffer class in Java is used to create mutable (modifiable) strings. Unlike String,
StringBuffer objects can be modified without creating new objects.

Key Methods for Modifying

 append(): Adds text to the end of the buffer.


 insert(): Inserts text at a specified position.

 delete(): Removes characters from a substring.


 replace(): Replaces a substring with another string.
 reverse(): Reverses the contents of the buffer.

Example

java
Copy code
public class StringBufferExample {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("Hello");

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

// Insert
sb.insert(5, ",");
System.out.println(sb); // Output: Hello, World

// Delete
sb.delete(5, 6);
System.out.println(sb); // Output: Hello World

// Replace
sb.replace(6, 11, "Java");
System.out.println(sb); // Output: Hello Java

// Reverse
sb.reverse();
System.out.println(sb); // Output: avaJ olleH
}
}

Key Methods for Searching

 indexOf(): Returns the index of the first occurrence of a substring.


 lastIndexOf(): Returns the index of the last occurrence of a substring.

Example

java
Copy code
public class StringBufferSearchExample {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("Hello, World");

// Index of
int index = sb.indexOf("World");
System.out.println("Index of 'World': " + index); // Output: 7

// Last Index of
int lastIndex = sb.lastIndexOf("o");
System.out.println("Last index of 'o': " + lastIndex); // Output: 8
}
}

Multithreaded Programming Introduction

Multithreaded programming involves running multiple threads concurrently, which can improve
the performance of an application by taking advantage of multiple processors.

Need for Multiple Threads

 Parallelism: Threads allow for parallel execution of tasks, making efficient use of multi-
core processors.
 Responsiveness: In a GUI application, threads can keep the interface responsive while
performing background tasks.
 Resource Sharing: Threads within the same process share resources, making
communication between them easier and more efficient.

Multithreaded Programming for Multi-Core Processor

Java provides built-in support for multithreaded programming using the Thread class and the
Runnable interface.

Creating a Thread by Extending Thread


java
Copy code
public class MyThread extends Thread {
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println("Thread running: " + i);
try {
Thread.sleep(500); // Sleep for 500 milliseconds
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

public static void main(String[] args) {


MyThread t1 = new MyThread();
t1.start(); // Start the thread

// Main thread work


for (int i = 0; i < 5; i++) {
System.out.println("Main thread: " + i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

Creating a Thread by Implementing Runnable

java
Copy code
public class MyRunnable implements Runnable {
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println("Thread running: " + i);
try {
Thread.sleep(500); // Sleep for 500 milliseconds
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

public static void main(String[] args) {


Thread t1 = new Thread(new MyRunnable());
t1.start(); // Start the thread

// Main thread work


for (int i = 0; i < 5; i++) {
System.out.println("Main thread: " + i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

Thread States

A thread can be in one of several states:

 New: When a thread is created but not yet started.


 Runnable: When a thread is ready to run but waiting for CPU time.
 Blocked: When a thread is waiting for a monitor lock.
 Waiting: When a thread is waiting indefinitely for another thread to perform a particular
action.
 Timed Waiting: When a thread is waiting for a specified amount of time.
 Terminated: When a thread has completed its execution.

Thread Priorities

Each thread has a priority, which helps the thread scheduler decide which thread should run next.
Threads with higher priority are more likely to be executed.

Setting Thread Priority

java
Copy code
public class ThreadPriorityExample extends Thread {
public void run() {
System.out.println("Thread running: " + this.getName());
}

public static void main(String[] args) {


ThreadPriorityExample t1 = new ThreadPriorityExample();
ThreadPriorityExample t2 = new ThreadPriorityExample();

t1.setPriority(Thread.MIN_PRIORITY); // Priority 1
t2.setPriority(Thread.MAX_PRIORITY); // Priority 10

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

Synchronization
Synchronization is necessary when multiple threads need to access shared resources
concurrently. It prevents race conditions by ensuring that only one thread can access the resource
at a time.

Example of Synchronized Method

java
Copy code
class Counter {
private int count = 0;

public synchronized void increment() {


count++;
}

public int getCount() {


return count;
}
}

public class SynchronizationExample {


public static void main(String[] args) throws InterruptedException {
Counter counter = new Counter();

Thread t1 = new Thread(() -> {


for (int i = 0; i < 1000; i++) {
counter.increment();
}
});

Thread t2 = new Thread(() -> {


for (int i = 0; i < 1000; i++) {
counter.increment();
}
});

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

t1.join();
t2.join();

System.out.println("Count: " + counter.getCount()); // Output: 2000


}
}

Deadlock and Race Situations

 Deadlock: Occurs when two or more threads are blocked forever, each waiting on the
other.
 Race Condition: Occurs when two threads try to access and modify shared resources
concurrently, leading to unpredictable results.
Avoiding Deadlock

 Use a consistent order of acquiring locks.


 Use tryLock for timed locking attempts.
 Avoid holding multiple locks when possible.

Inter-Thread Communication

Java provides methods for inter-thread communication using wait(), notify(), and notifyAll()
methods.

Example

java
Copy code
class SharedResource {
private int value;
private boolean available = false;

public synchronized void put(int value) throws InterruptedException {


while (available) {
wait();
}
this.value = value;
available = true;
notifyAll();
}

public synchronized int get() throws InterruptedException {


while (!available) {
wait();
}
available = false;
notifyAll();
return value;
}
}

public class InterThreadCommunicationExample {


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

Thread producer = new Thread(() -> {


try {
for (int i = 0; i < 5; i++) {
resource.put(i);
System.out.println("Produced: " + i);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread consumer = new Thread(() -> {
try {
for (int i = 0; i < 5; i++) {
int value = resource.get();
System.out.println("Consumed: " + value);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});

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

Thread Class

The Thread class in Java is used to represent and control a thread of execution. A thread is a
lightweight subprocess, the smallest unit of processing.

Creating a New Thread

There are two main ways to create a new thread in Java:

1. By extending the Thread class


2. By implementing the Runnable interface

Extending the Thread Class

You can create a thread by creating a subclass of Thread and overriding its run method.

Example

java
Copy code
class MyThread extends Thread {
public void run() {
System.out.println("Thread is running...");
}
}

public class Main {


public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start(); // Start the thread
}
}
Implementing the Runnable Interface

You can create a thread by implementing the Runnable interface and passing an instance of your
class to a Thread object.

Example

java
Copy code
class MyRunnable implements Runnable {
public void run() {
System.out.println("Runnable is running...");
}
}

public class Main {


public static void main(String[] args) {
Thread thread = new Thread(new MyRunnable());
thread.start(); // Start the thread
}
}

Main Thread

The main thread is the initial thread that is executed when a Java application starts. It can create
additional threads.

Example
java
Copy code
public class Main {
public static void main(String[] args) {
// Get the reference to the main thread
Thread mainThread = Thread.currentThread();
System.out.println("Main thread name: " + mainThread.getName());

// Creating a new thread


Thread newThread = new Thread(() -> {
System.out.println("New thread is running...");
});
newThread.start(); // Start the new thread
}
}

Thread States

A thread can be in one of the following states:

1. NEW: The thread is created but not yet started.


2. RUNNABLE: The thread is ready to run and is waiting for CPU time.
3. BLOCKED: The thread is blocked and waiting for a monitor lock.

4. WAITING: The thread is waiting indefinitely for another thread to perform a particular action.

5. TIMED_WAITING: The thread is waiting for another thread to perform a particular action
within a specified waiting time.

6. TERMINATED: The thread has exited.

Example
java
Copy code
public class Main {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(() -> {
System.out.println("Thread state: " + Thread.currentThread().getState());
});

System.out.println("Thread state before start: " + thread.getState());


thread.start();
System.out.println("Thread state after start: " + thread.getState());

// Wait for the thread to terminate


thread.join();
System.out.println("Thread state after termination: " + thread.getState());
}
}

Thread Priorities

Thread priorities determine the relative importance of a thread. Threads with higher priority are
executed in preference to threads with lower priority.

Example
java
Copy code
public class Main {
public static void main(String[] args) {
Thread highPriorityThread = new Thread(() -> {
System.out.println("High priority thread is running...");
});

Thread lowPriorityThread = new Thread(() -> {


System.out.println("Low priority thread is running...");
});

highPriorityThread.setPriority(Thread.MAX_PRIORITY);
lowPriorityThread.setPriority(Thread.MIN_PRIORITY);

highPriorityThread.start();
lowPriorityThread.start();
}
}

Synchronization

Synchronization is used to control the access of multiple threads to shared resources to prevent
data inconsistency and ensure thread safety.

Synchronized Method

A method can be marked as synchronized to ensure that only one thread can execute it at a time.

Example

java
Copy code
class Counter {
private int count = 0;

public synchronized void increment() {


count++;
}

public int getCount() {


return count;
}
}

public class Main {


public static void main(String[] args) throws InterruptedException {
Counter counter = new Counter();

Thread t1 = new Thread(() -> {


for (int i = 0; i < 1000; i++) {
counter.increment();
}
});

Thread t2 = new Thread(() -> {


for (int i = 0; i < 1000; i++) {
counter.increment();
}
});

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

t1.join();
t2.join();

System.out.println("Count: " + counter.getCount()); // Should print 2000


}
}
Synchronized Block

A synchronized block can be used to synchronize only a part of a method.

Example

java
Copy code
class Counter {
private int count = 0;

public void increment() {


synchronized (this) {
count++;
}
}

public int getCount() {


return count;
}
}

public class Main {


public static void main(String[] args) throws InterruptedException {
Counter counter = new Counter();

Thread t1 = new Thread(() -> {


for (int i = 0; i < 1000; i++) {
counter.increment();
}
});

Thread t2 = new Thread(() -> {


for (int i = 0; i < 1000; i++) {
counter.increment();
}
});

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

t1.join();
t2.join();

System.out.println("Count: " + counter.getCount()); // Should print 2000


}
}

Deadlock and Race Situations

Deadlock
Deadlock is a situation in concurrent programming where two or more threads are blocked
forever, each waiting for the other to release a resource. This results in a standstill and the
application cannot proceed.

Example of Deadlock

java
Copy code
class Resource {
public synchronized void method1(Resource r) {
System.out.println(Thread.currentThread().getName() + " entered method1");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
r.method2(this);
}

public synchronized void method2(Resource r) {


System.out.println(Thread.currentThread().getName() + " entered method2");
}
}

public class DeadlockDemo {


public static void main(String[] args) {
final Resource r1 = new Resource();
final Resource r2 = new Resource();

Thread t1 = new Thread(() -> r1.method1(r2), "Thread 1");


Thread t2 = new Thread(() -> r2.method1(r1), "Thread 2");

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

In the above example, Thread 1 holds the lock on r1 and tries to lock r2, while Thread 2 holds the
lock on r2 and tries to lock r1. This creates a deadlock situation.

Race Conditions

Race conditions occur when the behavior of a program depends on the relative timing of the
execution of threads. If two or more threads modify shared data simultaneously, it can lead to
inconsistent or incorrect results.

Example of Race Condition

java
Copy code
class Counter {
private int count = 0;
public void increment() {
count++;
}

public int getCount() {


return count;
}
}

public class RaceConditionDemo {


public static void main(String[] args) throws InterruptedException {
Counter counter = new Counter();

Thread t1 = new Thread(() -> {


for (int i = 0; i < 1000; i++) {
counter.increment();
}
});

Thread t2 = new Thread(() -> {


for (int i = 0; i < 1000; i++) {
counter.increment();
}
});

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

t1.join();
t2.join();

System.out.println("Final count: " + counter.getCount()); // Expected 2000, but might be less


}
}

In this example, two threads increment the counter, leading to a race condition where the final
count may not be 2000 due to simultaneous access.

Inter-Thread Communication

Inter-thread communication is necessary to coordinate the actions of multiple threads. Java


provides various methods for threads to communicate and coordinate with each other.

Suspending, Resuming, and Stopping Threads

Java provides mechanisms to control the execution of threads. However, the use of suspend(),
resume(), and stop() methods is deprecated due to potential deadlocks and inconsistent states.
Instead, proper thread communication and synchronization techniques are recommended.

Using wait(), notify(), and notifyAll()


These methods are used for inter-thread communication and must be called within a
synchronized context.

Example

java
Copy code
class SharedResource {
private boolean available = false;

public synchronized void produce() {


while (available) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Producing...");
available = true;
notify();
}

public synchronized void consume() {


while (!available) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Consuming...");
available = false;
notify();
}
}

public class InterThreadCommunicationDemo {


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

Thread producer = new Thread(() -> {


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

Thread consumer = new Thread(() -> {


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

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

In this example, the producer and consumer threads use wait() and notify() for inter-thread
communication to ensure proper coordination.

Modern Approach: Using Lock and Condition

The java.util.concurrent.locks package provides Lock and Condition interfaces for more flexible and
modern thread control mechanisms.

Example

java
Copy code
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class SharedResourceWithLock {
private boolean available = false;
private final Lock lock = new ReentrantLock();
private final Condition condition = lock.newCondition();

public void produce() {


lock.lock();
try {
while (available) {
condition.await();
}
System.out.println("Producing...");
available = true;
condition.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}

public void consume() {


lock.lock();
try {
while (!available) {
condition.await();
}
System.out.println("Consuming...");
available = false;
condition.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}

public class InterThreadCommunicationWithLockDemo {


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

Thread producer = new Thread(() -> {


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

Thread consumer = new Thread(() -> {


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

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

In this example, ReentrantLock and Condition provide a more flexible way to manage inter-thread
communication, avoiding some of the issues with traditional synchronization methods.

Key Points
 Deadlock: Occurs when two or more threads are blocked forever, each waiting on the other.
 Race Conditions: Occur when the outcome of a program depends on the sequence or timing of
uncontrollable events.

 Inter-Thread Communication: Achieved using wait(), notify(), and notifyAll() within


synchronized blocks or methods.

 Deprecated Methods: suspend(), resume(), and stop() are deprecated due to safety concerns.

 Modern Approach: Use Lock and Condition from java.util.concurrent.locks for better thread
control.

Java Database Connectivity (JDBC) Introduction

JDBC is an API in Java that enables Java applications to interact with databases. It provides
methods to connect to the database, execute SQL queries, and retrieve results.

JDBC Architecture

The JDBC architecture consists of two main layers:

1. JDBC API: Provides the application-to-JDBC Manager connection.


2. JDBC Driver API: Supports the JDBC Manager-to-Driver connection.

Components of JDBC Architecture

1. DriverManager: Manages a list of database drivers. It matches connection requests from the java
application with the proper database driver using communication subprotocol.
2. Driver: Interface that handles the communications with the database server.

3. Connection: Interface that provides methods for connecting to a database.

4. Statement: Interface used for executing SQL statements.

5. ResultSet: Interface that represents the set of results returned by executing a statement.

6. SQLException: Exception class that provides information on a database access error or other
errors.

JDBC Driver Types

There are four types of JDBC drivers:

1. JDBC-ODBC Bridge Driver: Type 1


2. Native-API Driver: Type 2

3. Network Protocol Driver: Type 3

4. Thin Driver: Type 4

Installing MySQL and MySQL Connector/J

Installing MySQL

1. Download MySQL:
o Visit the MySQL download page.

o Select your operating system and download the appropriate installer.

2. Install MySQL:

o Run the installer and follow the installation steps.

o During installation, you'll be prompted to configure MySQL Server, create a root


password, and set up other configurations.

3. Start MySQL Server:

o Start the MySQL server from the command line or using the MySQL Workbench.

Installing MySQL Connector/J


1. Download MySQL Connector/J:
o Visit the MySQL Connector/J download page.

o Download the ZIP or TAR archive for your operating system.

2. Install MySQL Connector/J:

o Extract the downloaded archive to a directory of your choice.

o The mysql-connector-java-<version>.jar file will be in the extracted directory.

Setting Up JDBC Connection with MySQL

1. Add MySQL Connector/J to Your Project:


o If you are using an IDE like IntelliJ IDEA or Eclipse, add the mysql-connector-java-
<version>.jar file to your project's classpath.

o If you are using a build tool like Maven, add the dependency to your pom.xml:

xml
Copy code
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.25</version> <!-- Replace with the latest version -->
</dependency>

2. JDBC Connection Example:

java
Copy code
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class JDBCDemo {


public static void main(String[] args) {
// JDBC URL, username and password of MySQL server
String url = "jdbc:mysql://localhost:3306/mydatabase"; // Replace "mydatabase" with your database
name
String user = "root"; // Replace with your MySQL username
String password = "rootpassword"; // Replace with your MySQL password

// JDBC variables for opening and managing connection


Connection con = null;
Statement stmt = null;
ResultSet rs = null;

try {
// Opening database connection
con = DriverManager.getConnection(url, user, password);
// Creating statement object
stmt = con.createStatement();

// Executing SQL query


String query = "SELECT * FROM mytable"; // Replace "mytable" with your table name
rs = stmt.executeQuery(query);

// Iterating through the result set


while (rs.next()) {
int id = rs.getInt("id"); // Replace "id" with your column name
String name = rs.getString("name"); // Replace "name" with your column name
System.out.println("ID: " + id + ", Name: " + name);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try { if (rs != null) rs.close(); } catch (Exception e) { e.printStackTrace(); }
try { if (stmt != null) stmt.close(); } catch (Exception e) { e.printStackTrace(); }
try { if (con != null) con.close(); } catch (Exception e) { e.printStackTrace(); }
}
}
}

Steps Explained:

1. Load the JDBC Driver (Optional from JDBC 4.0 onwards as it is automatically loaded):

java
Copy code
Class.forName("com.mysql.cj.jdbc.Driver");
2. Establish a Connection:

java
Copy code
con = DriverManager.getConnection(url, user, password);
3. Create a Statement:

java
Copy code
stmt = con.createStatement();
4. Execute a Query:

java
Copy code
rs = stmt.executeQuery(query);
5. Process the Result Set:

java
Copy code
while (rs.next()) {
int id = rs.getInt("id");
String name = rs.getString("name");
System.out.println("ID: " + id + ", Name: " + name);
}
6. Close the Resources:

java
Copy code
try { if (rs != null) rs.close(); } catch (Exception e) { e.printStackTrace(); }
try { if (stmt != null) stmt.close(); } catch (Exception e) { e.printStackTrace(); }
try { if (con != null) con.close(); } catch (Exception e) { e.printStackTrace(); }

JDBC Environment Setup

To use JDBC, you need to set up the environment which involves the following steps:

1. Install a Database: For example, MySQL.


2. Download JDBC Driver: Download the JDBC driver for your database (e.g., MySQL
Connector/J for MySQL).

3. Add JDBC Driver to Project: Include the JDBC driver in your project's classpath.

Example: Setting Up MySQL with JDBC

Step 1: Install MySQL

Download and install MySQL from the official MySQL website.

Step 2: Download JDBC Driver

Download the MySQL Connector/J driver from the MySQL website.

Step 3: Add JDBC Driver to Project

Add the MySQL JDBC driver (JAR file) to your project's classpath. If you are using an IDE like
IntelliJ IDEA or Eclipse, you can add the JAR file through the project settings.

Establishing JDBC Database Connections

Steps to Establish a Connection

1. Load the JDBC Driver: The JDBC driver must be loaded before you can establish a connection.
2. Establish a Connection: Use DriverManager.getConnection to connect to the database.

3. Create a Statement Object: Use the Connection object to create a Statement object.

4. Execute SQL Query: Use the Statement object to execute SQL queries.

5. Process the ResultSet: If the query returns results, process the ResultSet object.

6. Close the Connection: Close the ResultSet, Statement, and Connection objects to free resources.
Example
java
Copy code
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.SQLException;

public class JDBCExample {


public static void main(String[] args) {
String jdbcURL = "jdbc:mysql://localhost:3306/mydatabase";
String jdbcUsername = "root";
String jdbcPassword = "password";

Connection connection = null;


Statement statement = null;
ResultSet resultSet = null;

try {
// Load the JDBC driver
Class.forName("com.mysql.cj.jdbc.Driver");

// Establish a connection
connection = DriverManager.getConnection(jdbcURL, jdbcUsername, jdbcPassword);

// Create a statement object


statement = connection.createStatement();

// Execute a query
String sql = "SELECT * FROM users";
resultSet = statement.executeQuery(sql);

// Process the ResultSet


while (resultSet.next()) {
int id = resultSet.getInt("id");
String name = resultSet.getString("name");
String email = resultSet.getString("email");

System.out.println("ID: " + id + ", Name: " + name + ", Email: " + email);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
// Close the ResultSet, Statement, and Connection
try {
if (resultSet != null) resultSet.close();
if (statement != null) statement.close();
if (connection != null) connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}

ResultSet Interface

The ResultSet interface represents the result set of a database query. It provides methods to iterate
through the results and retrieve data from the current row.

Key Methods of ResultSet

 next(): Moves the cursor to the next row.


 getInt(String columnLabel): Retrieves the value of the specified column as an int.

 getString(String columnLabel): Retrieves the value of the specified column as a String.

 close(): Closes the ResultSet object.

Example
java
Copy code
public class ResultSetExample {
public static void main(String[] args) {
String jdbcURL = "jdbc:mysql://localhost:3306/mydatabase";
String jdbcUsername = "root";
String jdbcPassword = "password";

try (Connection connection = DriverManager.getConnection(jdbcURL, jdbcUsername, jdbcPassword);


Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery("SELECT * FROM users")) {

while (resultSet.next()) {
int id = resultSet.getInt("id");
String name = resultSet.getString("name");
String email = resultSet.getString("email");

System.out.println("ID: " + id + ", Name: " + name + ", Email: " + email);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}

JavaFX GUI

Introduction to JavaFX
JavaFX is a software platform for creating and delivering desktop applications, as well as rich
internet applications (RIAs). It is intended to replace Swing as the standard GUI library for Java
SE.

Setting Up JavaFX

To use JavaFX, you need to include the JavaFX libraries in your project. This can be done by
downloading the JavaFX SDK and configuring your IDE to use it, or by adding dependencies to
your build file if you are using a build tool like Maven or Gradle.

Example: Basic JavaFX Application


java
Copy code
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class Main extends Application {


@Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Hello JavaFX!");

Button btn = new Button();


btn.setText("Say 'Hello World'");
btn.setOnAction(event -> System.out.println("Hello World!"));

StackPane root = new StackPane();


root.getChildren().add(btn);

Scene scene = new Scene(root, 300, 250);


primaryStage.setScene(scene);
primaryStage.show();
}

public static void main(String[] args) {


launch(args);
}
}

JavaFX Scene Builder

Introduction

JavaFX Scene Builder is a visual layout tool that lets you design JavaFX application user
interfaces without writing code. You can drag and drop UI components (buttons, labels, etc.) to
build your layout.

Using Scene Builder


1. Download and install JavaFX Scene Builder.
2. Open your FXML file with Scene Builder.

3. Design your UI using drag-and-drop.

4. Save the FXML file and integrate it with your JavaFX application.

Example: FXML File


xml
Copy code
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane xmlns:fx="http://javafx.com/fxml" fx:controller="sample.Controller">


<children>
<Button fx:id="button" layoutX="150.0" layoutY="150.0" mnemonicParsing="false" text="Click Me" />
</children>
</AnchorPane>

Example: Controller Class


java
Copy code
import javafx.fxml.FXML;
import javafx.scene.control.Button;

public class Controller {


@FXML
private Button button;

@FXML
private void initialize() {
button.setOnAction(event -> System.out.println("Button clicked!"));
}
}

JavaFX Application Window Structure

Main Components

 Stage: The top-level container.


 Scene: The container for all content in a scene graph.

 Scene Graph: The hierarchical tree of nodes.

Example: JavaFX Window Structure


java
Copy code
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

public class Main extends Application {


@Override
public void start(Stage primaryStage) {
primaryStage.setTitle("JavaFX App Window Structure");

BorderPane root = new BorderPane();


Label label = new Label("Welcome to JavaFX");
root.setCenter(label);

Scene scene = new Scene(root, 400, 300);


primaryStage.setScene(scene);
primaryStage.show();
}

public static void main(String[] args) {


launch(args);
}
}

Displaying Text and Images

Displaying Text

You can use various JavaFX controls to display text, such as Label, Text, and TextArea.

Example: Displaying Text with Label

java
Copy code
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class Main extends Application {


@Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Display Text");

Label label = new Label("Hello, JavaFX!");


StackPane root = new StackPane();
root.getChildren().add(label);

Scene scene = new Scene(root, 300, 250);


primaryStage.setScene(scene);
primaryStage.show();
}

public static void main(String[] args) {


launch(args);
}
}

Displaying Images

You can display images using the ImageView class.

Example: Displaying an Image

java
Copy code
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class Main extends Application {


@Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Display Image");

Image image = new Image("file:example.jpg");


ImageView imageView = new ImageView(image);

StackPane root = new StackPane();


root.getChildren().add(imageView);

Scene scene = new Scene(root, 400, 300);


primaryStage.setScene(scene);
primaryStage.show();
}

public static void main(String[] args) {


launch(args);
}
}

Example: Displaying Text and Image Together


java
Copy code
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class Main extends Application {


@Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Display Text and Image");

Label label = new Label("Hello, JavaFX!");

Image image = new Image("file:example.jpg");


ImageView imageView = new ImageView(image);

VBox root = new VBox();


root.getChildren().addAll(label, imageView);

Scene scene = new Scene(root, 400, 300);


primaryStage.setScene(scene);
primaryStage.show();
}

public static void main(String[] args) {


launch(args);
}
}

Event Handling in JavaFX

Event handling in JavaFX allows your application to respond to user actions like button clicks,
key presses, and mouse movements.

Handling Action Events

The most common type of event is the action event, often associated with buttons.

Example: Handling Button Clicks

java
Copy code
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class Main extends Application {


@Override
public void start(Stage primaryStage) {
Button btn = new Button("Click Me");
btn.setOnAction(event -> System.out.println("Button Clicked!"));

StackPane root = new StackPane();


root.getChildren().add(btn);
Scene scene = new Scene(root, 300, 250);

primaryStage.setTitle("Event Handling Example");


primaryStage.setScene(scene);
primaryStage.show();
}

public static void main(String[] args) {


launch(args);
}
}

Handling Key Events

You can also handle key events, such as key presses and key releases.

Example: Handling Key Presses

java
Copy code
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class Main extends Application {


@Override
public void start(Stage primaryStage) {
StackPane root = new StackPane();

Scene scene = new Scene(root, 300, 250);

scene.setOnKeyPressed(event -> {
switch (event.getCode()) {
case UP:
System.out.println("UP key pressed");
break;
case DOWN:
System.out.println("DOWN key pressed");
break;
default:
break;
}
});

primaryStage.setTitle("Key Event Handling Example");


primaryStage.setScene(scene);
primaryStage.show();
}

public static void main(String[] args) {


launch(args);
}
}

Laying Out Nodes in Scene Graph

JavaFX provides several layout panes to organize UI controls in a scene. Commonly used layout
panes include StackPane, HBox, VBox, BorderPane, and GridPane.

Example: Using Different Layout Panes

StackPane

java
Copy code
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class StackPaneExample extends Application {


@Override
public void start(Stage primaryStage) {
Button btn = new Button("Click Me");

StackPane root = new StackPane();


root.getChildren().add(btn);

Scene scene = new Scene(root, 300, 250);

primaryStage.setTitle("StackPane Example");
primaryStage.setScene(scene);
primaryStage.show();
}

public static void main(String[] args) {


launch(args);
}
}

HBox and VBox

java
Copy code
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class BoxLayoutExample extends Application {


@Override
public void start(Stage primaryStage) {
Button btn1 = new Button("Button 1");
Button btn2 = new Button("Button 2");
Button btn3 = new Button("Button 3");

HBox hbox = new HBox(10); // spacing of 10 pixels


hbox.getChildren().addAll(btn1, btn2, btn3);

VBox vbox = new VBox(10); // spacing of 10 pixels


vbox.getChildren().addAll(btn1, btn2, btn3);

Scene hboxScene = new Scene(hbox, 300, 250);


Scene vboxScene = new Scene(vbox, 300, 250);

primaryStage.setTitle("HBox and VBox Example");


primaryStage.setScene(hboxScene); // or vboxScene
primaryStage.show();
}

public static void main(String[] args) {


launch(args);
}
}

BorderPane

java
Copy code
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

public class BorderPaneExample extends Application {


@Override
public void start(Stage primaryStage) {
Button top = new Button("Top");
Button left = new Button("Left");
Button center = new Button("Center");
Button right = new Button("Right");
Button bottom = new Button("Bottom");

BorderPane borderPane = new BorderPane();


borderPane.setTop(top);
borderPane.setLeft(left);
borderPane.setCenter(center);
borderPane.setRight(right);
borderPane.setBottom(bottom);

Scene scene = new Scene(borderPane, 300, 250);

primaryStage.setTitle("BorderPane Example");
primaryStage.setScene(scene);
primaryStage.show();
}

public static void main(String[] args) {


launch(args);
}
}

GridPane

java
Copy code
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;

public class GridPaneExample extends Application {


@Override
public void start(Stage primaryStage) {
GridPane gridPane = new GridPane();

Button btn1 = new Button("Button 1");


Button btn2 = new Button("Button 2");
Button btn3 = new Button("Button 3");
Button btn4 = new Button("Button 4");

gridPane.add(btn1, 0, 0); // column 0, row 0


gridPane.add(btn2, 1, 0); // column 1, row 0
gridPane.add(btn3, 0, 1); // column 0, row 1
gridPane.add(btn4, 1, 1); // column 1, row 1

Scene scene = new Scene(gridPane, 300, 250);

primaryStage.setTitle("GridPane Example");
primaryStage.setScene(scene);
primaryStage.show();
}

public static void main(String[] args) {


launch(args);
}
}

Mouse Events

JavaFX provides the MouseEvent class to handle mouse actions such as clicking, pressing,
releasing, and moving the mouse.

Example: Handling Mouse Clicks


java
Copy code
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.StackPane;
import javafx.scene.text.Text;
import javafx.stage.Stage;

public class MouseEventExample extends Application {


@Override
public void start(Stage primaryStage) {
Text text = new Text("Click me!");

StackPane root = new StackPane();


root.getChildren().add(text);

Scene scene = new Scene(root, 300, 250);

scene.addEventFilter(MouseEvent.MOUSE_CLICKED, event -> {


System.out.println("Mouse Clicked: " + event.getSceneX() + ", " + event.getSceneY());
});

primaryStage.setTitle("Mouse Event Example");


primaryStage.setScene(scene);
primaryStage.show();
}

public static void main(String[] args) {


launch(args);
}
}

Example: Handling Mouse Movements


java
Copy code
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.StackPane;
import javafx.scene.text.Text;
import javafx.stage.Stage;

public class MouseMovementExample extends Application {


@Override
public void start(Stage primaryStage) {
Text text = new Text("Move the mouse over me!");

StackPane root = new StackPane();


root.getChildren().add(text);

Scene scene = new Scene(root, 300, 250);

scene.setOnMouseMoved(event -> {
text.setText("Mouse Moved: " + event.getSceneX() + ", " + event.getSceneY());
});
primaryStage.setTitle("Mouse Movement Example");
primaryStage.setScene(scene);
primaryStage.show();
}

public static void main(String[] args) {


launch(args);
}
}

Example: Handling Mouse Dragging


java
Copy code
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.StackPane;
import javafx.scene.text.Text;
import javafx.stage.Stage;

public class MouseDragExample extends Application {


@Override
public void start(Stage primaryStage) {
Text text = new Text("Drag me!");

StackPane root = new StackPane();


root.getChildren().add(text);

Scene scene = new Scene(root, 300, 250);

scene.setOnMouseDragged(event -> {
text.setText("Mouse Dragged: " + event.getSceneX() + ", " + event.getSceneY());
});

primaryStage.setTitle("Mouse Drag Example");


primaryStage.setScene(scene);
primaryStage.show();
}

public static void main(String[] args) {


launch(args);
}
}

You might also like