0% found this document useful (0 votes)
40 views

Oops Through Java by Vikram Dunga

oops java material from raghu engineering college ,andhra pradesh
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
40 views

Oops Through Java by Vikram Dunga

oops java material from raghu engineering college ,andhra pradesh
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 165

SYLLABUS

UNIT I
Introduction to OOP, procedural programming language and object oriented language,
principles of OOP, applications of OOP, history of java, java features, JVM, program
structure. Variables, primitive data types, identifiers, literals, operators, expressions,
precedence rules and associativity, primitive type conversion and casting, flow of control.
UNIT II
Classes and objects, class declaration, creating objects, methods, constructors and
constructor overloading, garbage collector, importance of static keyword and examples,
this keyword, arrays, command line arguments, nested classes, String and string han-
dling methods
UNIT III
Inheritance, types of inheritance, super keyword, final keyword, overriding and abstract
class. Interfaces, creating the packages, using packages, importance of CLASSPATH
and java.lang package. Exception handling, importance of try, catch, throw, throws and
finally block, user defined exceptions, Assertions
UNIT IV
Multithreading: introduction, thread life cycle, creation of threads, thread priorities, thread
synchronization, communication between threads. Reading data from files and writing
data to files, random access file. Collections: Collections Hierarchy; List - ArrayList,
LinkedList; Sets - HashSet, TreeSet, LinkedHashSet; Queue; Maps - HashMap, Tree-
Map, LinkedHashMap; Iterable, Iterator
UNIT V
Java FX GUI: Java FX Scene Builder, Java FX App Window Structure, displaying text
and image, event handling, laying out nodes in scene graph, mouse events

Text Books:
The complete Reference Java, 8th edition, Herbert Schildt, TMH.
Programming in JAVA, Sachin Malhotra, SaurabhChoudary, Oxford.
Introduction to java programming, 7th edition by Y Daniel Liang, Pearson.
JAVA 9 for Programmers, Paul Deitel, Harvey Deitel, 4th Edition, Pearson

Reference Books:
Dietal&Dietal, Java: How to Program, 8th Edition, PHI, 2010
C. S. Horstmann and G. Cornell, Core Java, Vol 1. Fundamentals, 7th Edition, Pearson-
Education, 2004
C. Horstmann, BIG JAVA Compatible with Java 5 & 6, 3rd Edition, Wiley Publishers, 2008



Experiments:

Exercise - 1 (Basics, Operators, Expressions)


a) Write a Java program to display default value of all primitive data type of Java
b) Write a Java program that display the roots of a quadratic equation ax2+bx=0. Calculate
the discriminate D and basing on value of D, describe the nature of root.
c) Five Bikers Compete in a race such that they drive at a constant speed which may or may
not be the same as the other. To qualify the race, the speed of a racer must be more than the
average speed of all 5 racers. Take as input the speed of each racer and print back the speed
of qualifying racers.
d) Write a case study on public static void main(250 words)

Exercise - 2 (Control-flow, Arrays)


a) Write a Java program to search for an element in a given list of elements using binary
search mechanism.
b) Write a Java program to sort for an element in a given list of elements using bubble sort

Exercise – 3 (Class, Object)


a) Write a Java program to implement class mechanism. – Create a class, methods and
invoke them inside main method.
c) Write a Java program to swap the pairs of characters of a string. If the string contains an
odd number of characters then the last character remains as it is.

Exercise - 4 (Methods)
a) Write a Java program to implement constructor overloading.
b) Write a Java program implement method overloading.

Exercise - 5 (Inheritance)
a) Write a Java program to implement Single Inheritance
b) Write a Java program to implement multi level Inheritance
c) Write a Java program give example for “super” keyword.

Exercise - 6 (Abstract Class, Interface)


a) Write a Java program for abstract class to find areas of different shapes
b) Write a Java program to implement Interface. What kind of Inheritance can be achieved

Exercise – 7 (Packages)
a) Write a Java program illustrate class path
b) Write a case study on including in class path in your os environment of your package.
c) Write a Java program that import and use the defined your package in the previous
Problem
Exercise - 8 (Exception)

a) Write a Java program that describes exception handling mechanism


b) Write a Java program illustrating Multiple catch clauses
Exercise – 9 (Runtime Polymorphism)
a) Write a Java program that implements Runtime polymorphism
b) Write a case study on run time polymorphism, inheritance that implements in
above problem

Exercise – 10 (User defined Exception)

a) Write a Java program to illustrating throw


b) Write a Java program to illustrating finally
c) Write a Java program to handle User Defined Exception

Exercise – 11 (Threads)

a) Write a Java program that creates threads by extending Thread class .First thread
display
“Good Morning “every 1 sec, the second thread displays “Hello “every 2 seconds and
the
third display “Welcome” every 3 seconds ,(Repeat the same by implementing Runna-
ble)
b) Write a program illustrating isAlive and join ()

Exercise - 12 (Collections)

a) Write a Java program to update an array list element by the given element.
b) Write a Java program to find numbers less than 7 in a tree set
c) Write a Java program to check whether a map contains key-value mappings (emp-
ty) or not.

Exercise - 13 (Java FX)

a) Write a Java program that import and use the user defined packages
b) Without writing any code, build a GUI that display text in label and image in an
ImageView (use JavaFX)
c) Build a Tip Calculator app using several JavaFX components and learn how to
respond to user interactions with the GUI
Unit I

Object-Oriented Programming (OOP) is a programming paradigm that


organizes software design around objects, which are instances of class-
es.
Objects encapsulate data (attributes) and behaviors (methods), enabling
modular and reusable code.
Key Features of OOPs:

Inheritance:
Allows you to create new classes (child classes) based on existing ones
(parent classes).
Child classes inherit properties and methods from their parent classes.
This promotes code reusability and reduces redundancy.
Encapsulation:
The process of bundling data (attributes) and methods (functions) that
operate on that data within a single unit (object).
Encapsulation hides the internal implementation details of an object, ex-
posing only the necessary interface.
This protects data integrity and promotes modularity.

Polymorphism:
The ability of objects of different types to be treated as if they were of the
same type.
It allows you to write code that can work with objects of different classes
in a uniform way.
Polymorphism is achieved through method overloading and method
overriding.
Abstraction:
The process of hiding unnecessary implementation details and exposing
only the essential features of an object.
Abstraction allows you to focus on the important aspects of an object
without getting bogged down in the details.
It promotes code readability and maintainability.
Additional Concepts:
Objects: Instances of a class.
Classes: Blueprints for creating objects.
Constructors: Special methods used to initialize objects.
Destructors: Special methods used to clean up resources when an object is de-
stroyed.
Method Overloading: Creating multiple methods with the same name but different
parameters.
Method Overriding: Defining a method in a child class with the same name and sig-
nature as a method in the parent class.

Benefits of OOP:

Modularity:
Code is organized into classes and objects, making it easier to manage, understand,
and update.
Reusability:
Classes can be reused in other programs or projects. Inheritance allows sharing of
functionality between classes.
Scalability:
OOP simplifies the process of building large and complex systems by breaking them
into smaller, manageable objects.
Maintainability:
Encapsulation ensures that changes in one part of the application do not impact oth-
ers. Well-defined interfaces reduce the ripple effect of changes.
Flexibility Through Polymorphism:
Allows for dynamic behavior and easy extension of functionality without altering ex-
isting code.
Improved Collaboration:
Teams can work on different objects or classes independently, enhancing productivi-
ty in collaborative environments.
Real-World Modeling:
OOP maps real-world entities and interactions into the programming domain, making
the design intuitive and relatable.
Secure Code:
Encapsulation and access control prevent unintended interference with an object’s
internal state.
Procedural Programming Language
Definition:
Procedural programming focuses on writing sequences of instructions or procedures
to perform tasks. Programs are structured as a series of steps or instructions execut-
ed in a specific order.
Key Features:
Functions: Code is organized into reusable procedures or functions.
Global and Local Variables: Variables can be global (shared) or local (specific to a
function).
Sequential Execution: Instructions are executed line-by-line, usually top to bottom.
No Objects: It does not use classes or objects for organization.
Examples:C,Pascal,Fortran
Advantages:
Simpler structure, making it easier to learn and understand.
Suitable for small programs or straightforward tasks.
Minimal overhead for performance-sensitive applications.
Disadvantages:
Difficult to manage for large or complex programs.
Poor code reuse; functions are less flexible compared to objects.
Maintenance can be challenging due to interdependence between procedures and
global variables.
Object-Oriented Programming Language (OOP)
OOP organizes code around objects and classes, focusing on encapsulating data and
functionality together. Objects are instances of classes and represent entities in a
program.
Key Features:
Encapsulation: Bundles data (attributes) and methods (functions) into objects.
Inheritance: Classes can inherit features from other classes.
Polymorphism: Objects can take on many forms (e.g., function overloading, method
overriding).
Abstraction: Hides implementation details and exposes only necessary functional-
ities.
Modularity: Code is divided into self-contained objects.
Examples:Java,Python (supports both paradigms),C++,Ruby..,
Advantages:
Highly modular and easier to manage for complex projects.
Code reuse is more effective due to inheritance and polymorphism.
Facilitates collaborative development and maintenance.
Disadvantages:
Can be more complex to learn and implement compared to procedural programming.
May introduce overhead, making it less efficient for performance-critical applications.
Applications of OOP:
Object-Oriented Programming (OOP) is widely used across industries and domains because it
provides a modular, reusable, and maintainable approach to software development. Below are some
Common applications of OOP:
1. Graphical User Interface (GUI) Applications
Why OOP? OOP’s encapsulation and inheritance make it ideal for GUI components like buttons,
windows, and text boxes, which share common features but also have unique behaviors.
Examples:
Windows operating system UI
Android/iOS mobile applications
Java Swing, JavaFX, and Python’s Tkinter for GUI development
2. Game Development
Games require entities like players, characters, and objects, each with unique attributes and behav-
iors. OOP’s inheritance and polymorphism simplify game design.
Examples:
Unity (C#): Game engines use OOP for creating scenes, characters, and game logic.
Unreal Engine (C++): Develops modular and reusable game components.
3. Web Development
OOP frameworks streamline building dynamic and scalable web applications by organizing code
into manageable components.
Examples:
Frameworks like Django (Python), Ruby on Rails (Ruby), and Laravel (PHP) use OOP principles.
Model-View-Controller (MVC) design pattern organizes web applications into logical structures.
4. Simulation and Modeling
Simulations often require realistic representation of entities with states and behaviors. OOP models
real-world systems effectively.
Examples:
Flight simulators for pilot training
Traffic simulations
Weather prediction systems
5. Enterprise Applications
Enterprise software, like ERP and CRM systems, benefit from the modularity and reusability of OOP,
which allows for easier updates and scaling.
Examples:
SAP, Oracle ERP systems
Salesforce CRM
6. Database Management Systems
Object-oriented databases represent data as objects, making them intuitive for OOP-
based applications.
Examples:
Object-oriented database management systems (OODBMS) like ObjectDB
Hibernate ORM for Java applications
7. Artificial Intelligence (AI) and Machine Learning (ML)
AI systems often involve complex systems like neural networks or decision trees,
which can be represented as objects with encapsulated functionality.
Examples:
Libraries like TensorFlow and PyTorch (Python) use OOP principles.
AI-driven chatbots and virtual assistants.
8. Real-Time Systems
OOP ensures reliability and modularity in systems requiring precise timing and multi-
tasking.
Examples:
Embedded systems in medical devices
Real-time monitoring systems in industries like aviation and automotive.
9. Network Protocol Design
Networking applications like protocol development often involve layered architec-
tures where inheritance and polymorphism simplify design.
Examples:
Network simulation tools
Communication protocols (e.g., TCP/IP implementations)
10. Mobile Applications
OOP supports building robust and maintainable mobile apps by organizing code into
logical classes and objects.
Examples:
Android apps (Java/Kotlin)
iOS apps (Swift/Objective-C)
11. Financial Systems
Financial applications like trading platforms and banking systems require secure,
scalable, and reusable code.
Examples:
Stock trading systems
Banking applications (e.g., payment gateways)
12. Operating Systems
Why OOP? Modern operating systems use OOP to manage hardware and software
interactions through modular design.
Examples:
Windows, macOS, and Linux kernel components use OOP concepts.
History of java:
The history of Java dates back to the early 1990s and is marked by its evolution into one of the most
widely used programming languages. Below is a detailed timeline of Java’s history:
. Origins (1990-1991)
Project Name: Oak
Initiation: Java was initiated by James Gosling, Mike Sheridan, and Patrick Naughton at Sun Mi-
crosystems.
Purpose: The project was intended to develop software for consumer electronic devices like set-top
boxes and televisions.
Language Design:
The team aimed to create a language that was platform-independent, robust, and capable of run-
ning on a variety of devices.
They based Oak on C and C++, but it avoided the complexities of these languages.
. Renaming and Public Launch (1994-1995)
Renaming: In 1994, Oak was renamed Java because “Oak” was already trademarked.
Reason for the Name: The name “Java” was inspired by Java coffee, a favorite of the development
team.
Platform Focus Shift:
The team realized the potential of the web and shifted focus from consumer electronics to the inter-
net.
Java was positioned as a language to create interactive web applications.
Key Event:
In 1995, Sun Microsystems officially launched Java with the slogan “Write Once, Run Anywhere”
(WORA), highlighting its platform independence.
HotJava, a web browser written in Java, demonstrated its capabilities.
3. Early Versions and Adoption (1996-1999)
Java 1.0 (1996):
First stable release.
Introduced the Java Development Kit (JDK) and Java Runtime Environment (JRE).
Key features: Applets, security features like the sandbox model, and garbage collection.
Java 2 (J2SE) (1998):
Enhanced performance and introduced the Swing GUI library and Collections Framework.
Segmented into different editions:
J2SE (Standard Edition): For desktop and server environments.
J2EE (Enterprise Edition): For large-scale enterprise applications.
J2ME (Micro Edition): For mobile devices.
Java features:
Java is a powerful, versatile, and widely used programming language known for its features that
make it ideal for a range of applications. Below are the key features of Java:
1. Platform Independence
“Write Once, Run Anywhere” (WORA):
Java programs are compiled into bytecode by the Java compiler.
This bytecode is platform-independent and runs on any machine with a Java Virtual Machine
(JVM).
Benefit: Eliminates the need for recompilation on different platforms.
2. Object-Oriented
Java is fully object-oriented, with features like:
Encapsulation: Data and methods are encapsulated within objects.
Inheritance: Classes can inherit properties and behaviors from other classes.
Polymorphism: Objects can take on multiple forms (e.g., method overloading/overriding).
Abstraction: Simplifies complex systems by showing only essential details.
Benefit: Enables modular, reusable, and maintainable code.
3. Simple
Java has a simple syntax derived from C++ but removes complex features like:
Pointers
Operator overloading
Multiple inheritance (replaced with interfaces)
Benefit: Easier to learn and use, especially for beginners
4. Secure
Java provides a secure runtime environment through:
Bytecode Verification: Ensures no malicious code is executed.
Security Manager: Controls access to system resources.
Sandboxing: Isolates untrusted code from affecting the system.
Benefit: Ideal for building secure applications, especially for the web.
5. Robust
Java emphasizes error-free programming with features like:
Automatic Garbage Collection: Manages memory automatically.
Exception Handling: Handles runtime errors gracefully.
Type Checking: Detects and eliminates type-related errors at compile-time.
Benefit: Reduces crashes and ensures program stability.
6. Multithreaded
Java supports multithreading, allowing multiple threads of execution to run concurrently.
Thread Class and Runnable Interface provide APIs for thread management.
Features like thread synchronization ensure safe thread communication.
Benefit: Efficiently handles tasks like animations, background tasks, and parallel processing.
7. Portable
Java’s platform independence ensures portability:
The same bytecode can run on different hardware and operating systems without
modification.
Benefit: Facilitates cross-platform development.

8. High Performance
While Java is not as fast as C or C++, its performance is optimized through:
Just-In-Time (JIT) Compiler: Converts bytecode to native machine code at runtime for
faster execution.
Efficient Garbage Collection: Reduces memory leaks.
Benefit: Balances performance with ease of development.
9. Distributed
Java has built-in support for distributed systems:
The Remote Method Invocation (RMI) and CORBA APIs allow programs to invoke
methods over a network.
Libraries like Java Socket Programming support communication between devices.
Benefit: Simplifies the creation of networked applications.
10. Dynamic
Java is dynamic because:
Classes are loaded into memory at runtime.
Reflection and dynamic method invocation allow for runtime behavior changes.
Supports integration with other languages via the JVM (e.g., Kotlin, Groovy).
Benefit: Provides flexibility for modern application requirements.
11. Extensible
Java’s modular architecture and a vast ecosystem of libraries and frameworks make it
highly extensible.
Benefit: Simplifies building complex, scalable applications.
12. Interpreted and Compiled
Java combines compilation (to bytecode) and interpretation (by the JVM).
Benefit: Enables platform independence while maintaining reasonable performance.
The Java Virtual Machine (JVM) is a core component of the Java platform that provides a runtime
environment for executing Java applications. It acts as a bridge between Java code and the under-
lying operating system, enabling Java’s “Write Once, Run Anywhere” (WORA) functionality.

Key Responsibilities of the JVM


Platform Independence:
The JVM executes bytecode, a platform-independent intermediate representation of Java code,
ensuring the same program runs on any system with a compatible JVM.
Execution of Java Programs:
Converts bytecode into machine-specific instructions using:
Interpreter: Executes bytecode line-by-line.
Just-In-Time (JIT) Compiler: Optimizes performance by translating frequently executed bytecode
into native machine code at runtime.
Memory Management:
Handles memory allocation and deallocation automatically through Garbage Collection, ensuring
efficient use of resources and preventing memory leaks.
Security:
Provides a secure execution environment by verifying bytecode before execution (Bytecode
Verifier) and isolating untrusted code using the Security Manager.
Multithreading Support:
Enables concurrent execution of threads, allowing efficient multitasking.
How JVM Works

Compilation:
Java source code (.java) is compiled into bytecode (.class) by the Java Compiler (javac).
Class Loading:
The JVM Class Loader loads the bytecode into memory.
Bytecode Verification:
The JVM checks the bytecode for security and correctness.
Execution:
The Execution Engine executes the bytecode:
Using the Interpreter for interpreting bytecode line-by-line.
Using the JIT Compiler to optimize and convert bytecode to native machine code for faster execution.

JVM in Different Java Editions


Standard Edition (Java SE):
JVM for general-purpose applications.
Enterprise Edition (Java EE):
JVM tailored for enterprise-level, distributed applications.
Micro Edition (Java ME):
JVM optimized for mobile and embedded systems.

2. Java Runtime Environment (JRE)


Definition:
The JRE is the software bundle that provides the environment for running Java applications. It in-
cludes the JVM and essential Java libraries and APIs.

Components:
JVM: Executes Java bytecode.
Core Libraries: Includes classes for file handling, networking, database connections, and more.
Supportive Tools: Such as configuration files and runtime tools.
Key Use:
Required for running Java applications but does not include tools for development (e.g., compilers).
3. Java Development Kit (JDK):
Definition::
The JDK is a complete software development kit (SDK) used to develop Java applications. It includes
the JRE, JVM, and additional tools required for development.

Components:
JRE: For running Java programs.
Development Tools:
Java Compiler (javac): Compiles Java source code (.java) into bytecode (.class).
Debugger (jdb): Debugs Java applications.
Archiver (jar): Packages multiple Java files into a single .jar file.
Documentation Tool (javadoc): Generates API documentation.
Other tools for monitoring, profiling, and packaging Java applications.
Key Use:
Developers need the JDK to write, compile, and debug Java programs.
Java program structure:
The structure of a Java program consists of several key components arranged in a
specific way to ensure the program runs correctly. Here’s a breakdown of the typical
structure of a Java program:

// 1. Package Declaration (optional)


package com.example;

// 2. Import Statements (optional)


import java.util.Scanner;

// 3. Class Declaration
public class Main {

// 4. Main Method
public static void main(String[] args) {

// 5. Statements and Code


System.out.println(“Hello, World!”);
}
}

Components of a Java Program:


1. Package Declaration (Optional)
Declares the package to which the class belongs.
Used for organizing related classes into namespaces.

2. Import Statements (Optional)


Import predefined or user-defined classes and packages into the program.
Allows access to Java’s standard libraries or custom code.
3. Class Declaration
A Java program must have at least one class.
The class name must match the file name if it’s the public class.
4. Main Method
The entry point for program execution.
public: Makes the method accessible to the JVM.
static: Allows the JVM to invoke the method without creating an object.
void: Indicates the method does not return a value.
String[] args: Allows command-line arguments to be passed to the program.
Variables:
In Java, variables are containers that store data values during program execution.
Each variable in Java must be declared with a specific type, which determines the kind
of data it can hold.
Types of Variables in Java
Java variables can be classified into three categories based on where they are de-
clared and how they are used:

a) Local Variables
Declared inside a method, constructor, or block.
Only accessible within the block where they are defined.
Must be initialized before use.

public class Example {


public void display() {
int localVar = 10; // Local variable
System.out.println(localVar);
}
}
b) Instance Variables
Declared inside a class but outside any method, constructor, or block.
Belong to an instance of the class (each object has its own copy).
Automatically initialized to their default values if not explicitly initialized.

public class Example {


int instanceVar = 5; // Instance variable

public void display() {


System.out.println(instanceVar);
}
}
c) Static Variables
Declared inside a class using the static keyword.
Belong to the class rather than an instance (shared across all objects).
Initialized only once when the class is loaded.

public class Example {


static int staticVar = 10; // Static variable

public static void display() {


System.out.println(staticVar);
}
}
a) Primitive Data Types
byte (1 byte): Stores integers from -128 to 127.
short (2 bytes): Stores integers from -32,768 to 32,767.
int (4 bytes): Stores integers from -2³¹ to 2³¹-1.
long (8 bytes): Stores large integers from -2⁶³ to 2⁶³-1.
float (4 bytes): Stores decimal numbers with single precision.
double (8 bytes): Stores decimal numbers with double precision.
char (2 bytes): Stores a single character or Unicode.
boolean (1 bit): Stores true or false

Variable Scope:
The scope of a variable defines where it can be accessed:

Local Scope: Variables defined within a method or block.


Instance Scope: Variables defined in a class and accessible to all non-static methods.
Class Scope: Static variables accessible across all instances of the class.

Final Variables:
Declared using the final keyword.
Their value cannot be changed after initialization.

identifiers:
In Java, identifiers are the names used to identify variables, methods, classes,
packages, or other elements in a program. They must follow specific rules and con-
ventions to ensure code readability and correctness.
DefinitionAn identifier is the name assigned to elements such as variables, methods,
classes, and arrays. For example, in the statement:
int age = 25;
age is an identifier for a variable.
Rules for Naming Identifiers
Identifiers can include:
Letters (A-Z or a-z).
Digits (0-9).
The dollar sign ($) or underscore (_).
int my_var = 10;
Cannot Start with a Digit:
Identifiers cannot begin with a number.
Valid: var1, num
Invalid: 1var, 123
No Reserved Keywords:
Reserved keywords in Java (e.g., class, static, if) cannot be used as identifiers.
Invalid: int class = 10;
Case-Sensitive:
Java is case-sensitive, so Variable and variable are distinct.
Example:
java
Copy code
int num = 10;
int Num = 20; // Different from `num`
No Special Characters (except _ and $):
Characters like @, #, &, !, and spaces are not allowed.
Invalid: my-var, my var
No Length Limit:
There is no strict limit on the length of identifiers, but they should be concise and mean-
ingful.
Conventions for Naming Identifiers
Although not mandatory, following Java’s naming conventions improves code readability:

Variables and Methods:


Use camelCase.
Start with a lowercase letter.
Examples:
java
Copy code
int studentAge;
void calculateTotal();
Classes:
Use PascalCase (capitalize each word).
Examples:
java
Copy code
class Student;
class EmployeeDetails;
Packages:
Use all lowercase letters.
Examples:
java
Copy code
package com.example;
Literals:
In Java, literals are the fixed values that appear directly in the code. They rep-
resent constant values and are assigned to variables or used in expressions. Java
supports several types of literals, categorized based on data types:
1. Integer Literals:
Represent whole numbers without fractional parts.
int a = 123; // Decimal (base 10)
int b = 0b101; // Binary (base 2) - starts with `0b`
int c = 017; // Octal (base 8) - starts with `0`
int d = 0xF; // Hexadecimal (base 16) - starts with `0x`

Key points:
Integer literals are of type int by default.
To specify a long literal, append an L or l:
java
Copy code
long e = 123L;

2. Floating-Point Literals:
Represent decimal or scientific notation values.

Examples:
double x = 3.14; // Double by default
float y = 3.14F; // Float (requires `F` or `f`)
double z = 1.23e5; // Scientific notation (1.23 × 10⁵)

Key points:
Defaults to double. Use F or f for float.
Scientific notation uses e or E (e.g., 1.2e3).
3.Character Literals:
Represent single Unicode characters enclosed in single quotes.

Examples:

char a = ‘A’; // Single character


char b = ‘\n’; // Escape sequences (e.g., newline)
char c = ‘\u0041’; // Unicode (e.g., ‘A’ in hexadecimal)
4. String Literals
Represent sequences of characters enclosed in double quotes.

Examples:
String str = “Hello, World!”;
5. Boolean Literals
Represent logical values.

Examples:
boolean flag = true;
boolean isDone = false;
6. Null Literal
Represents the absence of a value for object references.

Example:
String str = null;
7. Special Literals (Underscores in Numeric Literals)
Improves readability by allowing underscores in numeric values.

Examples:
int million = 1_000_000; // Easier to read
double pi = 3.14_159_265;

Operators

Java provides a wide variety of operators that perform operations on variables


and values.
These operators are grouped based on their functionality:
Java Expressions
In Java, an expression is a construct that produces a single value when
executed. It consists of variables, operators, literals, and method calls, which are
combined to produce a result.
1. Arithmetic Expressions:
Arithmetic expressions perform mathematical calculations.
Examples:
int a = 5, b = 10;
int sum = a + b; // Addition
int product = a * b; // Multiplication
int remainder = b % a; // Modulus .

2. Relational Expressions:
Relational expressions evaluate relationships between values and return a bool-
ean (true or false).
int a = 5, b = 10;
boolean result1 = a < b; // true
boolean result2 = a == b; // false
3. Logical Expressions:
Logical expressions combine or negate boolean values.
Examples:
boolean isAdult = true, hasPermission = false;
boolean canEnter = isAdult && hasPermission; // false
boolean needsConsent = !isAdult; // false
4. Assignment Expressions
Assignment expressions assign values to variables.
int a = 5; // Simple assignment
a += 10; // Compound assignment (a = a + 10)
5. Unary Expressions:
Unary expressions operate on a single operand.
int a = 10;
int b = -a; // Unary minus
a++; // Post-increment
++a; // Pre-increment
6. Ternary Expressions:
The ternary operator (? :) evaluates a condition and chooses between two
values.
int a = 5, b = 10;
int max = (a > b) ? a : b; // max is 10
7. Method Call Expressions:
Expressions that invoke methods and return values.
int length = “Hello”.length();
8. Cast Expressions:
Used to convert one data type to another explicitly.
Examples:
double d = 5.99;
int i = (int) d; // Explicit casting: i becomes 5
9. Object Creation Expressions:
Expressions that create objects using the new keyword.
Example:
String str = new String(“Hello, World!”);
Primitive type conversion and casting:
In Java, primitive type conversion and casting allow data to be transformed
from one type to another. These operations are essential when working with vari-
ables of different data types. Java supports both automatic type conversion (widen-
ing) and explicit type casting (narrowing).
1. Primitive Data Types in Java
Java has 8 primitive data types:
Numeric types:
Integer: byte, short, int, long
Floating-point: float, double
Character type: char
Boolean type: boolean
2. Type Conversion:
a. Widening Conversion (Automatic/Implicit)
Occurs when a value of a smaller data type is automatically converted to a larger data
type.
No data loss occurs during widening conversion.
Follows this order:

byte → short → int → long → float → double


Example:

int num = 100;


double d = num; // Automatically converts int to double
System.out.println(d); // Output: 100.0

b. Narrowing Conversion (Explicit/Manual)


Occurs when a value of a larger data type is converted to a smaller data type.
Must be explicitly specified using type casting.
May result in data loss or precision loss.
Follows the reverse order of widening:

double → float → long → int → short → byte


Example:

double d = 100.99;
int num = (int) d; // Explicitly cast double to int
System.out.println(num); // Output: 100 (decimal part is lost)
3. Type Casting
a. Implicit Casting (Widening)
Occurs automatically when the target type is larger than the source type.
int i = 42;
long l = i; // int to long
float f = l; // long to float
System.out.println(f); // Output: 42.0
b. Explicit Casting (Narrowing)
Requires explicit syntax using parentheses () when the target type is smaller.

double d = 42.56;
int i = (int) d; // double to int
System.out.println(i); // Output: 42
Flow of control:
flow of control determines the order in which statements, instructions,
or function calls are executed in a program. Java provides constructs to
manage this flow, enabling decision-making, looping, and branching.
Types of Flow of Control
Sequential Flow:

The default flow where statements are executed one after the other, from
top to bottom.
Example:
int x = 10;
System.out.println(x); // This line executes after the previous one.
Decision-Making (Selection):
Alters the flow based on conditions.
Constructs: if, if-else, if-else if, switch.
Looping (Iteration):
Repeats a block of code while a condition is true.
Constructs: for, while, do-while.
Branching:
Alters the normal sequence by jumping to another part of the code.
Constructs: break, continue, return.
Decision-Making Statements
a. if Statement
Executes a block of code if the condition is true.
if (condition) {
// Code to execute if condition is true
}
Example:

int age = 18;


if (age >= 18) {
System.out.println(“You are an adult.”);
}
b. if-else Statement
Adds an alternative path when the condition is false.

if (condition) {
// Code if condition is true
} else {
// Code if condition is false
}
Example:

int marks = 45;


if (marks >= 50) {
System.out.println(“Pass”);
} else {
System.out.println(“Fail”);
}
c. if-else if Ladder
Evaluates multiple conditions in sequence.

if (condition1) {
// Code if condition1 is true
} else if (condition2) {
// Code if condition2 is true
} else {
// Code if all conditions are false
}
Example:

int score = 85;


if (score >= 90) {
System.out.println(“Grade A”);
} else if (score >= 75) {
System.out.println(“Grade B”);
} else {
System.out.println(“Grade C”);
}
d. switch Statement
Selects one of many blocks of code to execute.

switch (expression) {
case value1:
// Code for case value1
break;
case value2:
// Code for case value2
break;
default:
// Code if no cases match
}
Example:

int day = 3;
switch (day) {
case 1:
System.out.println(“Monday”);
break;
case 2:
System.out.println(“Tuesday”);
break;
case 3:
System.out.println(“Wednesday”);
break;
default:
System.out.println(“Invalid day”);
}
Looping Statements:

a. for Loop
Repeats a block of code a specific number of times.

for (initialization; condition; update) {


// Code to execute in each iteration
}
Example:

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


System.out.println(“Count: “ + i);
}
b. while Loop
Repeats a block of code as long as the condition is true.

while (condition) {
// Code to execute while condition is true
}
Example:

int i = 1;
while (i <= 5) {
System.out.println(“Count: “ + i);
i++;
}
c. do-while Loop
Executes the block of code at least once, then repeats while the condition is true.

do {
// Code to execute
} while (condition);
Example:

int i = 1;
do {
System.out.println(“Count: “ + i);
i++;
} while (i <= 5);
Branching Statements:

a. break Statement:

Exits the current loop or switch statement.


Example in a loop:

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


if (i == 3) {
break; // Exits the loop when i is 3
}
System.out.println(“Count: “ + i);
}
b. continue Statement:
Skips the current iteration of a loop and proceeds with the next iteration. Example:

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


if (i == 3) {
continue; // Skips the iteration when i is 3
}
System.out.println(“Count: “ + i);
}
c. return Statement
Exits from the current method and optionally returns a value. Example:

public int add(int a, int b) {


return a + b; // Returns the sum
}
Example: Combining Constructs

public class ControlFlowExample {


public static void main(String[] args) {
int num = 5;

// Decision-making
if (num % 2 == 0) {
System.out.println(“Even number”);
} else {
System.out.println(“Odd number”);
}

// Looping
for (int i = 1; i <= 5; i++) {
if (i == 3) {
continue; // Skip when i is 3
}
System.out.println(“Iteration: “ + i);
}
}
}
Unit-II

Class:
A class is a blueprint or template for creating objects.
It defines the properties (fields or attributes) and behaviors (methods or functions) that
objects of the class can have.

Syntax for Defining a Class


class ClassName {
// Fields (properties)
dataType fieldName;

// Methods (behaviors)
returnType methodName(parameters) {
// Method body
}
}
Example: Defining a Class

class Car {
// Fields
String brand;
int speed;

// Constructor
Car(String brand, int speed) {
this.brand = brand;
this.speed = speed;
}

// Method
void displayInfo() {
System.out.println(“Brand: “ + brand + “, Speed: “ + speed);
}
}
Object:
An object is an instance of a class.
Objects are created from classes and have their own state (values of fields) and behavior (methods).
Creating an Object
Objects are created using the new keyword.

Syntax:

ClassName objectName = new ClassName(arguments);


Example: Creating Objects
java
Copy code
public class Main {
public static void main(String[] args) {
// Create an object of the Car class
Car myCar = new Car(“Toyota”, 120);
myCar.displayInfo(); // Output: Brand: Toyota, Speed: 120
}
}

Creating methods :
Creating methods in Java involves defining reusable blocks of code that perform specific tasks.
Methods help organize code, reduce redundancy, and improve readability and maintainability.

1. Components of a Method:
A method in Java has the following components:

a. Syntax

accessModifier returnType methodName(parameterList) {


// Method body
// Logic to perform the task
return value; // Required if returnType is not void
}
2. Types of Methods:

a. Parameterized Methods:
Methods that accept input parameters.
Example:

public int add(int a, int b) {


return a + b; // Returns the sum of a and b
}
b. Non-Parameterized Methods:
Methods that do not accept any parameters.
Example:

public void greet() {


System.out.println(“Hello, World!”);
}
c. Static Methods:
Methods that belong to the class rather than any object.
Example:

public static void show() {


System.out.println(“This is a static method.”);
}
3. Creating and Using Methods
a. Define a Method
Define methods inside a class.
Example:

class Calculator {
// Non-parameterized method
public void sayHello() {
System.out.println(“Hello from Calculator!”);
}

// Parameterized method
public int multiply(int a, int b) {
return a * b;
}
}
d. Non-Static Methods
Methods that belong to an object of the class.
Example:

public void display() {


System.out.println(“This is a non-static method.”);
}
Call a Method:
Non-Static Methods:
Requires an object of the class.

Calculator calc = new Calculator();


calc.sayHello(); // Call non-static method
int result = calc.multiply(3, 5);
System.out.println(“Result: “ + result); // Output: 15

Static Methods:

Called using the class name or directly (no object required).

class MathUtility {
public static int square(int x) {
return x * x;
}
}

int result = MathUtility.square(4); // Call static method


System.out.println(“Square: “ + result); // Output: 16

Constructors :
In Java, a constructor is a special method used to initialize objects.
It is called when an object of a class is created, and it sets up the initial state of that ob-
ject by
initializing its fields.

1. Characteristics of a Constructor
A constructor must have the same name as the class.
It does not have a return type, not even void.
It is automatically called when an object is created.
If no constructor is defined, Java provides a default constructor.

2. Types of Constructors
a. Default Constructor
A constructor without parameters.
Provided automatically by Java if no constructor is explicitly defined.
If you define a constructor, the default constructor is not automatically provided.
Ex:
class Student {
String name;
int age;

// Default constructor
public Student() {
name = “Unknown”;
age = 0;
}

void display() {
System.out.println(“Name: “ + name + “, Age: “ + age);
}
}

public class Main {


public static void main(String[] args) {
Student s = new Student(); // Calls the default constructor
s.display(); // Output: Name: Unknown, Age: 0
}
}
b. Parameterized Constructor:
A constructor with parameters used to initialize fields with specific values.
Allows objects to be created with custom initial states.

class Student {
String name;
int age;

// Parameterized constructor
public Student(String name, int age) {
this.name = name;
this.age = age;
}

void display() {
System.out.println(“Name: “ + name + “, Age: “ + age);
}
}

public class Main {


public static void main(String[] args) {
Student s1 = new Student(“Alice”, 20); // Calls parameterized constructor
Student s2 = new Student(“Bob”, 22);
s1.display(); // Output: Name: Alice, Age: 20
s2.display(); // Output: Name: Bob, Age: 22
}
}
c. No-Argument Constructor
A constructor that takes no parameters.
Often explicitly defined to initialize fields with default values.

class Car {
String brand;

// No-argument constructor
public Car() {
brand = “Toyota”;
}

void display() {
System.out.println(“Brand: “ + brand);
}
}
d. Copy Constructor:
Used to create a new object as a copy of an existing object.
Not provided by Java explicitly, but can be implemented manually.

class Student {
String name;
int age;

// Parameterized constructor
public Student(String name, int age) {
this.name = name;
this.age = age;
}

// Copy constructor
public Student(Student s) {
this.name = s.name;
this.age = s.age;
}

void display() {
System.out.println(“Name: “ + name + “, Age: “ + age);
}
}

public class Main {


public static void main(String[] args) {
Student s1 = new Student(“Alice”, 20);
Student s2 = new Student(s1); // Create a copy of s1
s2.display(); // Output: Name: Alice, Age: 20
}
}
3. Constructor Overloading:
Java supports constructor overloading, meaning a class can have multiple constructors
with different parameter lists. The appropriate constructor is chosen based on the argu-
ments passed during object creation.

Example:

class Rectangle {
int length, width;

// Default constructor
public Rectangle() {
length = 1;
width = 1;
}

// Parameterized constructor
public Rectangle(int length, int width) {
this.length = length;
this.width = width;
}

void display() {
System.out.println(“Length: “ + length + “, Width: “ + width);
}
}

public class Main {


public static void main(String[] args) {
Rectangle r1 = new Rectangle(); // Default constructor
Rectangle r2 = new Rectangle(5, 10); // Parameterized constructor
r1.display(); // Output: Length: 1, Width: 1
r2.display(); // Output: Length: 5, Width: 10
}
}
4. this() Keyword in Constructors

The this() keyword can be used to call another constructor within the same class. This
is useful for reusing code.

Example:

class Employee {
String name;
int age;

// Default constructor
public Employee() {
this(“Unknown”, 0); // Calls the parameterized constructor
}

// Parameterized constructor
public Employee(String name, int age) {
this.name = name;
this.age = age;
}

void display() {
System.out.println(“Name: “ + name + “, Age: “ + age);
}
}

public class Main {


public static void main(String[] args) {
Employee e1 = new Employee(); // Calls default constructor
Employee e2 = new Employee(“John”, 30); // Calls parameterized constructor
e1.display(); // Output: Name: Unknown, Age: 0
e2.display(); // Output: Name: John, Age: 30
}
}
5. Rules for Constructors
A constructor cannot have a return type (not even void).
If no constructor is defined, Java provides a default constructor.
Constructors can be overloaded.
The this keyword can be used to:
Refer to the current object.
Call another constructor within the same class.
The Garbage Collector (GC) in Java is a part of the Java Virtual Machine (JVM) respon-
sible for automatically managing memory. It reclaims memory occupied by objects that
are no longer in use, freeing developers from manually deallocating memory and reduc-
ing the chances of memory leaks.

1. Why is Garbage Collection Needed?


In Java, objects are created dynamically using the new keyword.
Once an object becomes unreachable or is no longer needed, its memory becomes eligi-
ble for garbage collection.
Java’s garbage collector automates this process, making memory management easier
for developers compared to languages like C/C++.
2. How Garbage Collection Works
Heap Memory:
All objects are stored in the heap.
The garbage collector monitors the heap and identifies objects that are no longer acces-
sible.
Reachability:
Objects are considered reachable if they:
Can be accessed directly from a thread or a static field.
Are referenced by other reachable objects.
Unreachable objects are eligible for garbage collection.
Finalization:
Before reclaiming memory, the garbage collector may invoke the object’s finalize() meth-
od to perform cleanup tasks.

Advantages of Garbage Collection:


Automatic Memory Management: Reduces developer burden.
Prevents Memory Leaks: Frees up unused memory.
Simplifies Development: No need to explicitly allocate or deallocate memory.
Safe: Avoids common errors like dangling pointers (common in C++).
importance of static keyword and examples:
The static keyword in Java is an important feature that allows fields, methods,
blocks, or nested classes to belong to the class rather than any instance of the class.
This means that static members are shared among all objects of a class, and they can be
accessed without creating an instance.
1. Importance of the static Keyword:
a. Memory Efficiency
Static members are allocated memory only once, at class loading time.
This reduces memory usage compared to instance members, which require memory for
each object.
b. Class-Level Access
Static members are associated with the class itself and can be accessed using the class
name.
This makes them useful for utility or helper methods.
c. Global Data
Static fields act as global variables shared by all instances of a class, ensuring consistent
values across objects.
d. Encapsulation of Constants
static is often used with final to define constants, making them accessible without creat-
ing an instance.
2. Use Cases of static Keyword
a. Static Variables (Class Variables)
A static variable is shared among all instances of the class.
Changes to a static variable by one object are reflected in all objects.

class Counter {
static int count = 0; // Static variable

public Counter() {
count++; // Increment count for every object created
}
public static void displayCount() {
System.out.println(“Count: “ + count);
}}
public class Main {
public static void main(String[] args) {
Counter c1 = new Counter();
Counter c2 = new Counter();
Counter c3 = new Counter();
// Accessing the static variable
Counter.displayCount(); // Output: Count: 3
}
}
b. Static Methods:
Static methods belong to the class and do not require an instance to be invoked.
They can access only static variables and call other static methods.
Example:

class MathUtils {
// Static method
public static int add(int a, int b) {
return a + b;
}

public static int multiply(int a, int b) {


return a * b;
}
}

public class Main {


public static void main(String[] args) {
// Calling static methods without creating an object
System.out.println(“Sum: “ + MathUtils.add(5, 10)); // Output: Sum: 15
System.out.println(“Product: “ + MathUtils.multiply(5, 10)); // Output: Product: 50
}
}
c. Static Blocks:
A static block is used for initializing static variables or executing code at the time of class loading.
It runs only once, before the main method or any static method is called.
Example:

class Config {
static String appName;

// Static block
static {
appName = “MyApplication”;
System.out.println(“Static block executed”);
}
}

public class Main {


public static void main(String[] args) {
System.out.println(“App Name: “ + Config.appName); // Output: Static block executed
// App Name: MyApplication
}
}
this keyword:
In Java, the this keyword is a reference to the current object of a class. It is primar-
ily used to eliminate ambiguity between instance variables and parameters, and to refer
to the current object in various scenarios.

1. Importance of this Keyword


The this keyword is essential for:

Distinguishing instance variables from parameters when they share the same name.
Referring to the current object in methods or constructors.
Method chaining for cleaner and more compact code.
Calling one constructor from another (constructor chaining).
2. Uses of this Keyword
a. To Refer to Instance Variables
When local variables (like parameters) have the same name as instance variables, this is
used to differentiate between them.

Example:

class Student {
String name;

public Student(String name) {


this.name = name; // ‘this.name’ refers to the instance variable
}

void display() {
System.out.println(“Name: “ + name);
}
}

public class Main {


public static void main(String[] args) {
Student s = new Student(“Alice”);
s.display(); // Output: Name: Alice
}
}
b. To Call Another Constructor in the Same Class:

The this() keyword can be used to call another constructor of the same class. This is known as con-
structor chaining.

Example:

class Employee {
String name;
int age;

// Constructor 1
public Employee() {
this(“Unknown”, 0); // Calls Constructor 2
}

// Constructor 2
public Employee(String name, int age) {
this.name = name;
this.age = age;
}

void display() {
System.out.println(“Name: “ + name + “, Age: “ + age);
}
}

public class Main {


public static void main(String[] args) {
Employee e1 = new Employee(); // Calls Constructor 1
Employee e2 = new Employee(“John”, 30); // Calls Constructor 2
e1.display(); // Output: Name: Unknown, Age: 0
e2.display(); // Output: Name: John, Age: 30
}
}
Arrays:
In Java, an array is a data structure that stores a fixed-size sequential collection
of elements of the same type. It is a fundamental and commonly used way to organize
and access data in Java programs.

1. Features of Arrays in Java


Fixed Size: The size of an array is specified at the time of its creation and cannot be
changed later.
Homogeneous Data: All elements in an array must be of the same data type.
Zero-Based Indexing: Array indices start from 0 and go up to length - 1.
Stored in Heap Memory: Arrays are objects in Java, even if they hold primitive types,
and are stored in the heap.
Efficient Access: Arrays allow efficient random access using indices.

2. Declaring and Initializing Arrays:


a. Declaring an Array:
Arrays in Java are declared using square brackets ([]) after the data type or variable
name.

// Syntax
dataType[] arrayName; // Preferred
dataType arrayName[]; // Valid but less common
Examples:

int[] numbers; // Array to store integers


String[] names; // Array to store strings

b. Creating an Array:
Arrays are created using the new keyword, specifying the type and size.

arrayName = new dataType[size];


Example:

int[] numbers = new int[5]; // Creates an array of size 5


c. Initializing an Array:
You can initialize arrays at the time of declaration or later.

Numeric arrays (e.g., int[], float[]) are initialized to 0.


boolean[] is initialized to false.
Object arrays (e.g., String[]) are initialized to null.

int[] numbers = new int[3]; // {0, 0, 0}


boolean[] flags = new boolean[2]; // {false, false}
Explicit Initialization:

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


String[] names = {“Alice”, “Bob”, “Charlie”};
3. Accessing Array Elements:
Array elements are accessed using their index. The index must be an integer.

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

// Accessing elements
System.out.println(numbers[0]); // Output: 10
System.out.println(numbers[3]); // Output: 40

// Updating elements
numbers[2] = 100;
System.out.println(numbers[2]); // Output: 100

4. Iterating Over Arrays

a. Using a for Loop

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

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


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

b. Using an Enhanced for Loop

for (int num : numbers) {


System.out.println(num);
}
5. Types of Arrays:

a. Single-Dimensional Arrays:
A single row or list of elements.

int[] arr = {1, 2, 3, 4};


b. Multi-Dimensional Arrays
Arrays that have more than one dimension, commonly 2D arrays.

Declaration and Initialization:

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

System.out.println(matrix[1][2]); // Output: 6
Iterating Over a 2D Array:

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


for (int j = 0; j < matrix[i].length; j++) {
System.out.print(matrix[i][j] + “ “);
}
System.out.println();
}
6. Common Array Operations

a. Finding the Length of an Array

Use the .length property.

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


System.out.println(numbers.length); // Output: 3

c. Sorting an Array

Use the Arrays.sort() method.

import java.util.Arrays;

int[] numbers = {5, 2, 8, 1};


Arrays.sort(numbers);
8. Practical Example:

Example: Find the Maximum Element in an Array

public class Main {


public static void main(String[] args) {
int[] numbers = {5, 12, 8, 20, 7};
int max = numbers[0];

for (int num : numbers) {


if (num > max) {
max = num;
}
}

System.out.println(“Maximum value: “ + max); // Output: Maximum value: 20


}
}
Command-Line Arguments in Java:
Command-line arguments in Java allow users to pass data to a program at runtime through the com-
mand line. These arguments are supplied to the main() method as an array of String objects (String[]
args).
1. Structure of Command-Line Arguments
The main() method in Java is defined as:

public static void main(String[] args)


args is the parameter that holds the command-line arguments.
Each argument is stored as a String in the args array.
The arguments are indexed, starting from args[0] to args[args.length - 1].

2. How to Provide Command-Line Arguments


Command-line arguments are supplied when executing the program via a terminal or command
prompt.

java MyProgram arg1 arg2 arg3


Here, arg1, arg2, and arg3 are command-line arguments.
These will be stored in args[0], args[1], and args[2], respectively.

3. Example Program
Example 1: Printing Command-Line Arguments

public class CommandLineExample {


public static void main(String[] args) {
// Check if arguments are provided
if (args.length == 0) {
System.out.println(“No arguments provided.”);
} else {
System.out.println(“Command-line arguments:”);
for (int i = 0; i < args.length; i++) {
System.out.println(“args[“ + i + “]: “ + args[i]);
}
}
}
}
Execution:

java CommandLineExample Hello World Java


Output:

Command-line arguments:
args[0]: Hello
args[1]: World
args[2]: Java
4. Use Cases of Command-Line Arguments:

a. Passing Numerical Values:


Command-line arguments are always String by default. You can convert them to other
data types using methods like Integer.parseInt() or Double.parseDouble().
public class AddNumbers {
public static void main(String[] args) {
if (args.length < 2) {
System.out.println(“Please provide two numbers.”);
} else {
int num1 = Integer.parseInt(args[0]);
int num2 = Integer.parseInt(args[1]);
System.out.println(“Sum: “ + (num1 + num2));
} }

Nested Classes in Java:


A nested class is a class defined inside another class in Java.
Nested classes are used to logically group classes that are only used in one place, im-
proving code readability and encapsulation.
Nested classes have access to the members of their enclosing class, including private
members.

1. Types of Nested Classes


Java supports the following types of nested classes:

a. Static Nested Class


Defined with the static modifier.
Can be accessed without creating an instance of the enclosing class.
Can only access the static members of the enclosing class.
b. Non-Static Inner Class (Inner Class)
Does not have the static modifier.
Tied to an instance of the enclosing class and can access its instance members.
Requires an instance of the enclosing class to be instantiated.
c. Local Inner Class
Defined inside a block, such as a method or constructor.
Scope is limited to the block in which it is defined.
d. Anonymous Inner Class
A special type of local inner class without a name.
Defined and instantiated in a single statement.
Typically used to implement interfaces or extend classes in a concise way.
2. Static Nested Class:
Characteristics
Associated with the enclosing class, not its instance.
Can access only static members of the enclosing class directly.
Syntax:

class OuterClass {
static class StaticNestedClass {
void display() {
System.out.println(“Inside Static Nested Class”);
}
}
}
Example

public class Main {


static class StaticNested {
static void staticMethod() {
System.out.println(“Static method in static nested class”);
}

void instanceMethod() {
System.out.println(“Instance method in static nested class”);
}
}

public static void main(String[] args) {


// Calling static method
Main.StaticNested.staticMethod();

// Creating an instance of the static nested class


Main.StaticNested nested = new Main.StaticNested();
nested.instanceMethod();
}
}
3. Non-Static Inner Class:

Requires an instance of the enclosing class.


Can access both static and instance members of the enclosing class.
Syntax:

class OuterClass {
class InnerClass {
void display() {
System.out.println(“Inside Non-Static Inner Class”);
}
}
}
Example

public class Outer {


private String message = “Hello from Outer”;

class Inner {
void display() {
System.out.println(message);
}
}

public static void main(String[] args) {


Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
inner.display();
}}
4. Local Inner Class:

Defined inside a method or block.


Can access local variables of the enclosing block only if they are final or effectively final.
Has limited scope to the enclosing block.
Syntax

class OuterClass {
void someMethod() {
class LocalInnerClass {
void display() {
System.out.println(“Inside Local Inner Class”);
}
}
LocalInnerClass inner = new LocalInnerClass();
inner.display();
}
}
Example

public class Main {


void printNumbers() {
final int limit = 5; // Effectively final

class LocalInner {
void display() {
System.out.println(“Counting up to “ + limit);
for (int i = 1; i <= limit; i++) {
System.out.println(i);
}
}
}
5. Anonymous Inner Class:

Does not have a name.


Used to create a subclass or implement an interface on the fly.
Commonly used for event handling or quick implementation.
Syntax:

interface Greeting {
void sayHello();
}

class Main {
public static void main(String[] args) {
Greeting greet = new Greeting() {
@Override
public void sayHello() {
System.out.println(“Hello from Anonymous Inner Class”);
}
};
greet.sayHello();
}
}
Example:

import java.util.Timer;
import java.util.TimerTask;

public class Main {


public static void main(String[] args) {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println(“Task executed using an Anonymous Inner Class!”);
}
}, 1000);
}
}
Strings in Java:
A string is a sequence of characters. Strings are one of the most commonly used data types and
are represented by the String class in the java.lang package. Strings are immutable, meaning once cre-
ated, their values cannot be changed.

1. Creating Strings
Strings can be created in two ways:

a. Using String Literals


If a string is created using a literal, it is stored in the string pool.
If a string with the same content already exists in the pool, it is reused.

String str1 = “Hello”;


String str2 = “Hello”; // Points to the same string in the pool
b. Using the new Keyword:
A new String object is created in the heap memory every time, even if the content is the same.

String str1 = new String(“Hello”);


String str2 = new String(“Hello”); // Creates a new object in memory

2. Important Properties of Strings:


Immutable:
Strings cannot be changed once created. Operations that appear to modify a string (like concatenation)
actually create a new string.
Stored in String Pool: Java optimizes memory usage by storing string literals in a pool.
Supports Unicode: Java strings support Unicode, allowing them to represent international characters.

Method Description Example


length() Returns the length of the string. “Hello”.length() → 5
charAt(index) Returns the character at the specified “Hello”.charAt(1) → ‘e’
index.
substring(beginIndex) Returns a substring starting from the “Hello”.substring(2) →
specified index. “llo”
substring(beginIndex, endIn- Returns a substring between the speci- “Hello”.substring(1, 4) →
dex) fied indices (endIndex is exclusive). “ell”
toUpperCase() Converts all characters to uppercase. “hello”.toUpperCase() →
“HELLO”
toLowerCase() Converts all characters to lowercase. “HELLO”.toLowerCase()
→ “hello”
equals(Object) Compares two strings for equality “Hello”.equals(“hello”) →
(case-sensitive) false
equalsIgnoreCase(String) Compares two strings for equality, ig- “Hello”.equalsIgnore-
noring case. Case(“hello”) → true
contains(CharSequence) Checks if the string contains the “Hello”.contains(“ell”) → true
specified sequence.
indexOf(String) Returns the index of the first “Hello”.indexOf(“l”) → 2
occurrence of the substring.
lastIndexOf(String) Returns the index of the last “Hello”.lastIndexOf(“l”) → 3
occurrence of the substring.
replace(char, char) Replaces all occurrences of a “Hello”.replace(‘l’, ‘p’) → “Hep-
character with another. po”
replaceAll(String, String) Replaces all occurrences of a “Java is fun”.replaceAll(“fun”,
substring with another. “cool”) → “Java is cool”
trim() Removes leading and trailing “ Hello “.trim() → “Hello”
whitespace.
split(String) Splits the string into an array “a,b,c”.split(“,”) → {“a”, “b”, “c”}
based on the specified delimiter.

4. String Concatenation:

a. Using + Operator

String s1 = “Hello”;
String s2 = “World”;
String result = s1 + “ “ + s2;
System.out.println(result); // Output: Hello World

b. Using concat() Method

String s1 = “Hello”;
String s2 = “World”;
String result = s1.concat(“ “).concat(s2);
System.out.println(result); // Output: Hello World

5. String Comparison:
a. Using equals()
Compares the content of two strings (case-sensitive).

String s1 = “Hello”;
String s2 = “Hello”;
System.out.println(s1.equals(s2)); // Output: true

b. Using ==
Checks if two references point to the same object (not content).

String s1 = “Hello”;
String s2 = new String(“Hello”);
System.out.println(s1 == s2); // Output: false
c. Using compareTo()
Compares two strings lexicographically. Returns:

0 if both strings are equal.


A negative value if the first string is lexicographically smaller.
A positive value if the first string is lexicographically larger.

String s1 = “Apple”;
String s2 = “Banana”;
System.out.println(s1.compareTo(s2)); // Output: -1

6. Immutable Strings
Strings in Java are immutable, meaning any modification creates a new string object instead of altering
the original.

String s1 = “Hello”;
String s2 = s1.concat(“ World”);
System.out.println(s1); // Output: Hello
System.out.println(s2); // Output: Hello World

7. Mutable Alternatives: StringBuilder and StringBuffer


For scenarios involving frequent modifications to strings, use StringBuilder or StringBuffer:

StringBuilder: Faster and not thread-safe.


StringBuffer: Thread-safe but slower due to synchronization.
Example Using StringBuilder

StringBuilder sb = new StringBuilder(“Hello”);


sb.append(“ World”);
System.out.println(sb); // Output: Hello World
8. String Pool:
What is String Pool? A special memory region in the heap where string literals are stored.
When a string literal is created, the JVM checks the pool:
If the literal exists, the reference is reused.
If not, a new string is added to the pool.
Unit III
Inheritance in Java
Inheritance is one of the core features of object-oriented programming (OOP).
It allows a class (child class) to inherit the properties and behavior (fields and meth-
ods) of another class (parent class). This promotes code reuse and establishes a
natural hierarchy between classes.
1. Key Concepts
Parent Class (Superclass):
The class whose properties and methods are inherited.
Example: Animal.
Child Class (Subclass):
The class that inherits the parent class’s properties and methods.
Example: Dog (inherits from Animal).

Inheritance Syntax:

Use the extends keyword for inheritance.

class Parent {
// Fields and methods
}
class Child extends Parent {
// Additional fields and methods
}

1. Single Inheritance:
Definition: A class inherits from one parent class.
Usage: Models a straightforward parent-child relationship.

class Parent {
void display() {
System.out.println(“Parent class method”);
}
}

class Child extends Parent {


void show() {
System.out.println(“Child class method”);
}
}
public class Main {
public static void main(String[] args) {
Child obj = new Child();
obj.display(); // Inherited from Parent
obj.show(); // From Child
}
}
Output:
Parent class method
Child class method

2. Multilevel Inheritance
Definition: A class inherits from a class, which in turn inherits from another class.
Usage: Models a chain of inheritance.

class Grandparent {
void greet() {
System.out.println(“Hello from Grandparent”);
}
}
class Parent extends Grandparent {
void display() {
System.out.println(“Parent class method”);
}
}
class Child extends Parent {
void show() {
System.out.println(“Child class method”);
}
}
public class Main {
public static void main(String[] args) {
Child obj = new Child();
obj.greet(); // From Grandparent
obj.display(); // From Parent
obj.show(); // From Child
}
}
3. Hierarchical Inheritance
Definition: Multiple classes inherit from a single parent class.
Usage: Models multiple specializations of a general concept.

class Parent {
void greet() {
System.out.println(“Parent class method”);
}
}

class Child1 extends Parent {


void show() {
System.out.println(“Child1 class method”);
}
}

class Child2 extends Parent {


void display() {
System.out.println(“Child2 class method”);
}
}

public class Main {


public static void main(String[] args) {
Child1 obj1 = new Child1();
Child2 obj2 = new Child2();

obj1.greet(); // From Parent


obj1.show(); // From Child1

obj2.greet(); // From Parent


obj2.display(); // From Child2
}
}
o/p
Parent class method
Child1 class method
Parent class method
Child2 class method
4. Multiple Inheritance (Through Interfaces)
Definition: A class can inherit from multiple interfaces. Java does not support mul-
tiple inheritance with classes directly to avoid the Diamond Problem.
Usage: Combines functionality from multiple interfaces.
Example

interface A {
void methodA();
}

interface B {
void methodB();
}

class C implements A, B {
public void methodA() {
System.out.println(“Method from Interface A”);
}

public void methodB() {


System.out.println(“Method from Interface B”);
}
}

public class Main {


public static void main(String[] args) {
C obj = new C();
obj.methodA();
obj.methodB();
}
}

o/p
Method from Interface A
Method from Interface B
5. Hybrid Inheritance:
Definition: A combination of two or more types of inheritance (like hierarchical and multiple).
Java does not support hybrid inheritance directly with classes due to single inheritance, but it can
be achieved using interfaces.
Usage: Complex inheritance relationships.

Example

interface Parent1 {
void method1();
}

interface Parent2 {
void method2();
}

class Child implements Parent1, Parent2 {


public void method1() {
System.out.println(“Method from Parent1”);
}

public void method2() {


System.out.println(“Method from Parent2”);
}
}

public class Main {


public static void main(String[] args) {
Child obj = new Child();
obj.method1();
obj.method2();
}
}
Output:

Method from Parent1


Method from Parent2

Why Java Does Not Support Multiple Inheritance with Classes?


Java does not allow multiple inheritance with classes to avoid ambiguity
caused by the Diamond Problem. For example, if a class inherits from two parent
classes with the same method, the compiler cannot decide which method to inherit.
class A {
void display() {
System.out.println(“Class A”);
}
}

class B {
void display() {
System.out.println(“Class B”);
}
}

// Not allowed in Java


class C extends A, B {
// Ambiguity: Which display() to inherit?
}
To resolve this, Java uses interfaces for multiple inheritance.

The super Keyword in Java


The super keyword in Java is used to refer to the parent class (superclass) of the current object. It
allows the child class to access fields, methods, or constructors of the parent class.

1. Uses of the super Keyword


a. Access Parent Class Fields
If a child class has fields with the same name as the parent class, the super keyword can be used to
refer to the parent class field.

class Parent {
String name = “Parent”;
}

class Child extends Parent {


String name = “Child”;

void display() {
System.out.println(“Child name: “ + name); // Refers to the child class field
System.out.println(“Parent name: “ + super.name); // Refers to the parent class field
}}
public class Main {
public static void main(String[] args) {
Child obj = new Child();
obj.display();
}}
Output:
Child name: Child
Parent name: Parent
b. Access Parent Class Methods
The super keyword can be used to call methods of the parent class if the child class overrides them.

class Parent {
void greet() {
System.out.println(“Hello from Parent!”);
}}
class Child extends Parent {
void greet() {
System.out.println(“Hello from Child!”);
}
void display() {
super.greet(); // Calls the parent class method
greet(); // Calls the child class method
}}
public class Main {
public static void main(String[] args) {
Child obj = new Child();
obj.display();
}}
Output:
Hello from Parent!
Hello from Child!

c. Invoke Parent Class Constructor:


The super keyword can be used to call the constructor of the parent class. This must be the first
statement in the child class constructor.
class Parent {
Parent() {
System.out.println(“Parent class constructor”);
}}
class Child extends Parent {
Child() {
super(); // Calls the parent class constructor
System.out.println(“Child class constructor”);
}}

public class Main {


public static void main(String[] args) {
Child obj = new Child();
}}
Output:
Parent class constructor
Child class constructor

super must the First Statement in the Constructor:

When used in a constructor, super() must be the first line of the constructor.
The final Keyword in Java:
The final keyword in Java is a modifier used to apply restrictions on classes,
methods, and variables. It ensures that certain aspects of a program’s behavior re-
main unchangeable.

1. Use Cases of final


a. Final Variables:
A final variable is a constant. Once initialized, its value cannot be changed.
Syntax:

final dataType variableName = value;


Example

class Example {
public static void main(String[] args) {
final int MAX_VALUE = 100;
System.out.println(“Max Value: “ + MAX_VALUE);

// MAX_VALUE = 200; // Compilation error: cannot reassign a final variable


}
}
Output:
Max Value: 100
b. Final Methods
A final method cannot be overridden by subclasses.
Use Case: To prevent subclasses from altering the behavior of a method.

class Parent {
final void display() {
System.out.println(“This is a final method.”);
}
}

class Child extends Parent {


// void display() { // Compilation error: Cannot override final method
// System.out.println(“Overridden method.”);
// }
}
Output:

This is a final method.


c. Final Classes
A final class cannot be subclassed (inherited).
Use Case: To prevent extension of a class, ensuring its implementation remains un-
changed.
Example

final class Parent {


void display() {
System.out.println(“This is a final class.”);
}
}

Difference Between final, finally, and finalize

keyword usage

final A modifier used to declare constants, prevent method overriding, and


inheritance.
finally A block used in exception handling to execute code regardless of whether
an exception occurs.
finalize A method called by the garbage collector before an object is destroyed.

Method Overloading in Java


Method overloading is a feature in Java that allows a class to have multiple methods
with the same name but different parameter lists. It improves code readability and
reusability by allowing methods to perform similar operations but with different types or
numbers of arguments.

note:
All overloaded methods must have the same name.
Different Parameter Lists:
Methods are differentiated by the number, type, or order of parameters.
It does not depend on the return type of the method.
Compile-Time Polymorphism:

Method overloading is an example of compile-time polymorphism because the deci-


sion about which method to call is made during compilation.
Examples of Method Overloading
1. Overloading by Changing the Number of Parameters
java
Copy code
class Calculator {
int add(int a, int b) {
return a + b;
}

int add(int a, int b, int c) {


return a + b + c;
}
}

public class Main {


public static void main(String[] args) {
Calculator calc = new Calculator();
System.out.println(“Sum of 2 numbers: “ + calc.add(10, 20));
System.out.println(“Sum of 3 numbers: “ + calc.add(10, 20, 30));
}
}
Output:
Sum of 2 numbers: 30
Sum of 3 numbers: 60

2. Overloading by Changing Parameter Types

class Calculator {
int multiply(int a, int b) {
return a * b;
}

double multiply(double a, double b) {


return a * b;
}
}

public class Main {


public static void main(String[] args) {
Calculator calc = new Calculator();
System.out.println(“Multiplication of integers: “ + calc.multiply(5, 10));
System.out.println(“Multiplication of doubles: “ + calc.multiply(2.5, 4.0));
}
}
Output:

Multiplication of integers: 50
Multiplication of doubles: 10.0
Rules for Method Overloading
Return Type Does Not Differentiate Methods:

Methods cannot be overloaded by changing only the return type.


Example (Not Allowed):

class Example {
void display() {}
int display() {} // Compilation error
}
Static Methods Can Be Overloaded:

Static methods can also be overloaded as long as the parameter list differs.
Cannot Overload by Changing Access Modifiers:

Changing the public, private, or protected modifier does not constitute overloading.

Why Use Method Overloading?


Readability:
Same operation can be implemented with variations without using different method names.’
Reusability:
Multiple versions of a method can share the same name, avoiding redundant code.
Flexibility:
Allows methods to handle different types or numbers of arguments.
class Printer {
void print(String message) {
System.out.println(“String Message: “ + message);
}
void print(int number) {
System.out.println(“Integer Value: “ + number);
}
void print(String message, int number) {
System.out.println(“Message: “ + message + “, Number: “ + number);
}}

public class Main {


public static void main(String[] args) {
Printer printer = new Printer();
printer.print(“Hello World”);
printer.print(42);
printer.print(“Java”, 2023);
}}
Output:
String Message: Hello World
Integer Value: 42
Message: Java, Number: 2023
Method Overriding in Java:
Method overriding is a feature in Java that allows a subclass to provide a specific imple-
mentation for a method that is already defined in its parent class. This enables runtime
polymorphism and dynamic method dispatch.

Same Method Signature:

The method in the child class must have the same name, return type (or a covariant re-
turn type), and parameters as the method in the parent class.
Inheritance:

Overriding occurs only in the context of inheritance (i.e., between a superclass and its
subclass).

Runtime Polymorphism:
The method to be called is determined at runtime based on the object’s actual type, not
the reference type.
Cannot Override:
final methods: Methods declared final in the parent class cannot be overridden.
Static methods: These are not overridden; they are hidden.
Private methods: These are not visible to the subclass and hence cannot be overridden.

Rules for Method Overriding


Access Modifier:

The overriding method cannot have a more restrictive access modifier than the method
in the parent class.
For example, if the parent class method is protected, the overriding method cannot be
private.
Covariant Return Type:

The overriding method can return a subclass of the object type returned by the parent
method.
Annotations:

Use @Override to indicate that a method is being overridden. This is not mandatory but
helps to catch errors during compilation.
Constructor Overriding:

Constructors cannot be overridden as they are not inherited by subclasses.


Ex:

class Parent {
void display() {
System.out.println(“Display method in Parent class”);
}
}

class Child extends Parent {


@Override
void display() {
System.out.println(“Display method in Child class”);
}
}

public class Main {


public static void main(String[] args) {
Parent obj = new Child(); // Upcasting
obj.display(); // Calls the overridden method in Child class
}
}
Abstract Classes in Java:
An abstract class in Java is a class that cannot be instantiated on its own.
It is designed to act as a base class for other classes and may include abstract methods (meth-
ods without a body) as well as non-abstract methods (methods with implementation).
Abstract classes provide a way to enforce a structure while still allowing for flexibility in imple-
mentation.

Features of Abstract Classes


Cannot Be Instantiated.

Abstract classes cannot be used to create objects directly.


Abstract Methods:

These are methods declared without a body. Subclasses must provide their implementation.
Syntax:

abstract returnType methodName(parameters);

Non-Abstract Methods:

Abstract classes can include fully implemented methods.

Constructors:

Abstract classes can have constructors, which can be called when an object of a subclass is
created.
Can Contain Variables and Static Members:

Abstract classes can declare instance variables, static variables, and static methods.
Inheritance:

Any subclass of an abstract class must either implement all abstract methods or also be declared
abstract.

abstract class ClassName {


// Abstract method (no body)
abstract void abstractMethod();

// Non-abstract method (with body)


void concreteMethod() {
System.out.println(“This is a concrete method.”);
}
}
Example:

abstract class Animal {


abstract void sound(); // Abstract method

void eat() { // Concrete method


System.out.println(“This animal eats food.”);
}
}

class Dog extends Animal {


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

class Cat extends Animal {


@Override
void sound() {
System.out.println(“Cat meows.”);
}
}

public class Main {


public static void main(String[] args) {
Animal dog = new Dog();
dog.sound(); // Output: Dog barks.
dog.eat(); // Output: This animal eats food.

Animal cat = new Cat();


cat.sound(); // Output: Cat meows.
cat.eat(); // Output: This animal eats food.
}
}

When to Use Abstract Classes


Partial Implementation:
Use abstract classes when you want to provide partial implementation for subclasses.
Shared Behavior:
Use when multiple classes share some behavior (concrete methods) but need to enforce other
specific behaviors (abstract methods).
Polymorphism:
Abstract classes allow using a common reference type while calling methods implemented differ-
ently by subclasses.
2. Abstract Class with Constructor

abstract class Vehicle {


String brand;

// Constructor
Vehicle(String brand) {
this.brand = brand;
}

abstract void start();

void displayBrand() {
System.out.println(“Brand: “ + brand);
}
}
class Car extends Vehicle {
Car(String brand) {
super(brand);
}

@Override
void start() {
System.out.println(“Car starts with a key.”);
}
}
public class Main {
public static void main(String[] args) {
Vehicle car = new Car(“Toyota”);
car.displayBrand(); // Output: Brand: Toyota
car.start(); // Output: Car starts with a key.
}
}
Interfaces in Java:
An interface in Java is a blueprint for a class that contains method declarations (abstract
methods) and static or default methods (since Java 8).
Interfaces are used to achieve abstraction and multiple inheritance in Java.

Syntax of an Interface:

interface InterfaceName {
// Abstract method (implicitly public and abstract)
void abstractMethod();

// Default method (Java 8+)


default void defaultMethod() {
System.out.println(“Default method in interface.”);
}

// Static method (Java 8+)


static void staticMethod() {
System.out.println(“Static method in interface.”);
}
}
Implementing an Interface
A class implements an interface using the implements keyword and must provide implementa-
tions for all the abstract methods.
interface Animal {
void sound(); // Abstract method
}
class Dog implements Animal {
@Override
public void sound() {
System.out.println(“Dog barks.”);
}
}
public class Main {
public static void main(String[] args) {
Animal dog = new Dog();
dog.sound(); // Output: Dog barks.
}
}
Multiple Interfaces and Multiple Inheritance
Java does not support multiple inheritance through classes but allows a class to implement
multiple interfaces.
interface A {
void methodA();
}
interface B {
void methodB();
}

class C implements A, B {
@Override
public void methodA() {
System.out.println(“Method A”);
}

@Override
public void methodB() {
System.out.println(“Method B”);
}}
public class Main {
public static void main(String[] args) {
C obj = new C();
obj.methodA(); // Output: Method A
obj.methodB(); // Output: Method B
}
}
Advantages of Interfaces

Achieving Multiple Inheritance:


Java supports multiple inheritance through interfaces.

Encapsulation:
Interfaces help separate implementation details from functionality.

Flexibility:
Different classes can implement the same interface in different ways.

Loosely Coupled Systems:


Interfaces promote loose coupling by defining contracts.

Packages
A package in Java is a namespace that organizes classes and interfaces, making code eas-
ier to manage and avoid name conflicts. Packages also help control access and organize the
structure of large applications.

Types of Packages in Java


Built-in Packages:
Predefined packages such as java.util, java.io, java.lang, etc.
User-defined Packages:
Packages created by the programmer to group related classes and interfaces.
Advantages of Packages
Organizes Code:
Group related classes and interfaces into logical modules.
Prevents Name Conflicts:
Classes in different packages can have the same name.
Access Protection:
Use protected and default access levels for package-level protection.
Reusability:
Classes from a package can be reused in other programs.
Creating a Package:

Use the package keyword as the first statement in the file.


Save the file in a directory that matches the package name.
Syntax
package packageName;

public class ClassName {


public void display() {
System.out.println(“This is a method from the package.”);
}
}
Steps for Create a directory for the package:

For a package named mypackage, create a folder called mypackage.


Write the class file and include the package declaration.
Compile the file:
Use javac -d . ClassName.java. The -d flag specifies the destination of the compiled file.
Use the class in another program by importing the package.
Example: Creating and Using a Package

Step 1: Create a Package


Create a file named MyClass.java in a folder called mypackage.

// File: mypackage/MyClass.java

package mypackage;

public class MyClass {


public void displayMessage() {
System.out.println(“Hello from MyClass in mypackage!”);
}
}
Compile it:
javac -d . MyClass.java
This will create the mypackage directory with the compiled .class file.

Step 2: Use the Package


Create another file in the same directory or another directory.

// File: Main.java
import mypackage.MyClass; // Import the package

public class Main {


public static void main(String[] args) {
MyClass obj = new MyClass();
obj.displayMessage();
}
}
Access Modifiers in Java:
Access modifiers in Java determine the visibility and accessibility of classes, methods, construc-
tors, and variables. They help implement encapsulation and control how components interact
within a program.

Types of Access Modifiers


1.Public
2.Protected
3.Default (Package-Private)
4.Private

Classpath in Java: Importance and Usage


The classpath in Java is a parameter that specifies the location of classes and packages required
by the Java application during runtime or compilation. It acts as a search path for the Java Virtual
Machine (JVM) and Java Compiler to locate .class files.
Key Features of Classpath
Specifies Locations:
It tells the JVM where to look for user-defined classes and packages.
Includes Libraries:
You can include external .jar files, directories, and other resources.
Customizable:
You can set the classpath through environment variables, IDE configurations, or com-
mand-line arguments.
Default Behavior:
If no classpath is specified, the JVM uses the current directory (.) as the default classpath.
Why Is Classpath Important?
Dependency Resolution:
Ensures that the JVM can find all necessary .class files and libraries.
Modularity:
Helps in organizing projects by dividing them into packages and external libraries.
Error Prevention:
Properly setting the classpath avoids ClassNotFoundException and NoClassDefFoundError at
runtime.
Integration:
Essential for linking third-party libraries or modules in your Java application.

Setting the Classpath

1. Command-Line Setting
Temporary Classpath Setting: Use the -classpath or -cp option with javac or java.

java -cp path_to_classes MainClass


Example:
javac -cp lib/mylibrary.jar src/MainClass.java
java -cp lib/mylibrary.jar;bin MainClass
Note: Use ; as a separator on Windows and : on macOS/Linux.

2. Environment Variable
Set the CLASSPATH environment variable.

Windows:
set CLASSPATH=path1;path2;...

Example: Setting Classpath


Directory Example
Create a class file:

// File: MyClass.java
package mypackage;

public class MyClass {


public void greet() {
System.out.println(“Hello from MyClass!”);
}
}
Compile:

javac -d . MyClass.java
Run using classpath:

java -cp . mypackage.MyClass


java.lang Package in Java:
The java.lang package is one of the core packages in Java and is automatically imported
into every Java program. It contains classes and interfaces fundamental to Java programming,
including essential types like String, Math, Integer, and runtime functionalities.
Key Features of the java.lang Package
No Explicit Import Required:

It is automatically imported into every Java program.

Essential for Core Programming:


Contains fundamental classes and interfaces required for standard Java operations.

Provides Utility Classes:


Includes classes for string manipulation, mathematical operations, system I/O, and thread manage-
ment.
Exception Handling in Java

Exception handling in Java is a mechanism to handle runtime errors, ensuring that the normal flow
of a program is not disrupted. It allows a program to catch and resolve errors gracefully instead of
abruptly terminating execution.

Exception:
An exception is an event that disrupts the normal flow of a program.
Examples: Dividing by zero, accessing an invalid array index, file not found.

Error:
An error represents serious problems that applications should not try to handle
(e.g., OutOfMemoryError, StackOverflowError).

Exception Hierarchy:

Throwable: The parent class of all exceptions.


Error: Represents critical errors (e.g., hardware or JVM issues).
Exception: Represents conditions a program might want to handle.
Checked Exceptions: Exceptions that must be handled or declared in the method signature.
Unchecked Exceptions (Runtime Exceptions): Exceptions that can occur during runtime but do
not require explicit handling.
What are Java Exceptions?
In Java, Exception is an unwanted or unexpected event, which occurs during the execution of a
program, i.e. at run time, that disrupts the normal flow of the program’s instructions. Exceptions
can be caught and handled by the program. When an exception occurs within a method, it creates
an object.
This object is called the exception object. It contains information about the exception, such as the
name and description of the exception and the state of the program when the exception occurred.

Major reasons why an exception Occurs:


• Invalid user input
• Device failure
• Loss of network connection
• Physical limitations (out-of-disk memory)
• Code errors
• Out of bound
• Null reference
• Type mismatch
• Opening an unavailable file
• Database errors
• Arithmetic errors
Methods to print the Exception information:

1. printStackTrace():
This method prints exception information in the format of the Name of the exception: description of
the exception, stack trace.
2. toString() :
The toString() method prints exception information in the format of the Name of the exception: de-
scription of the exception.
3. getMessage() :
The getMessage() method prints only the description of the exception.

Blocks and Keywords Used For Exception Handling


1. try in Java:
The try block contains a set of statements where an exception can occur.

try
{
// statement(s) that might cause exception
}

2. catch in Java:
The catch block is used to handle the uncertain condition of a try block. A try block is always followed
by a catch block, which handles the exception that occurs in the associated try block.

catch
{
// statement(s) that handle an exception
// examples, closing a connection, closing
// file, exiting the process after writing
// details to a log file.
}

1. Try-Catch Block
The try block contains code that might throw an exception, and the catch block contains code to han-
dle the exception.

try {
int result = 10 / 0; // Will throw ArithmeticException
} catch (ArithmeticException e) {
System.out.println(“Cannot divide by zero: “ + e);
}
2. Finally Block:
The finally block is used to execute important cleanup code (like closing a file or database connec-
tion) regardless of whether an exception occurred.

try {
int result = 10 / 2;
System.out.println(result);
} catch (ArithmeticException e) {
System.out.println(“Exception occurred”);
} finally {
System.out.println(“Execution completed”);
}
Output:

Copy code
5
Execution completed

3. Throwing Exceptions:
The throw keyword is used to explicitly throw an exception.

public void checkAge(int age) {


if (age < 18) {
throw new IllegalArgumentException(“Age must be 18 or above”);
}
}
4. Declaring Exceptions with throws:

The throws keyword is used in method declarations to indicate that a method might throw excep-
tions.

public void readFile(String fileName) throws IOException {


FileReader file = new FileReader(fileName);
}
Custom Exceptions:
You can create your own exception classes by extending the Exception or RuntimeException
class.
class CustomException extends Exception {
public CustomException(String message) {
super(message);
}
}

public class Main {


public static void main(String[] args) {
try {
throw new CustomException(“This is a custom exception”);
} catch (CustomException e) {
System.out.println(e.getMessage());
}
}
}
Example:

try {
int result = 10 / 0;
String str = null;
System.out.println(str.length());
} catch (ArithmeticException | NullPointerException e) {
System.out.println(“Exception occurred: “ + e);
}
Example:

public class JavaExceptionExample{


public static void main(String args[]){
try{
//code that may raise exception
int data=100/0;
}catch(ArithmeticException e)
{
System.out.println(e);
}
//rest code of the program
System.out.println(“rest of the code...”);
}
}

Example:
public class Main {
public static void main(String[ ] args) {
try {
int[] myNumbers = {1, 2, 3};
System.out.println(myNumbers[10]);
} catch (Exception e) {
System.out.println(“Something went wrong.”);
}
}
}

Example:
public class Main {
public static void main(String[] args) {
try {
int[] myNumbers = {1, 2, 3};
System.out.println(myNumbers[10]);
} catch (Exception e) {
System.out.println(“Something went wrong.”);
} finally {
System.out.println(“The ‘try catch’ is finished.”);
}
}
}
Using throw keyword:

public class Main {


static void checkAge(int age) {
if (age < 18) {
throw new ArithmeticException(“Access denied - You must be at least 18 years old.”);
}
else {
System.out.println(“Access granted - You are old enough!”);
}
}

public static void main(String[] args) {


checkAge(15); // Set age to 15 (which is below 18...)
}
}

Assertions in Java:
Assertions in Java are used to test assumptions about the program’s logic. They are pri-
marily intended for debugging purposes to identify and fix bugs early in the development pro-
cess. Assertions help validate that a program is functioning as expected by checking conditions
and throwing errors if those conditions are violated.

Simple Assertion: assert expression;


Assertion with Message: assert expression : message;
example:

public class AssertionDemo {


public static void main(String[] args) {
int age = 15;

// Basic assertion
assert age >= 18 : “Age must be at least 18”;

System.out.println(“Age is valid”);
}
}
o/p:
Exception in thread “main” java.lang.AssertionError: Age must be at least 18

Enabling and Disabling Assertions:


By default, assertions are not evaluated during program execution.
Enable Assertions:
Use the -ea or -enableassertions JVM option.
java -ea AssertionDemo
Disable Assertions:
Use the -da or -disableassertions JVM option. [java -da AssertionDemo]
Unit IV

Multithreading:
Multithreading is a feature of Java that allows multiple threads to run concur-
rently within a program. Threads are lightweight sub-processes, the smallest unit of
processing in a multitasking system. Multithreading enables efficient CPU utilization
and smoother user experiences in applications.

Thread:
A thread is a single sequence of execution within a program.
In Java, threads are represented by the Thread class or by implementing the Runna-
ble interface.

Multitasking:
Process-based Multitasking: Executing multiple processes simultaneously.
Thread-based Multitasking: Executing multiple threads within the same program si-
multaneously.

Concurrency:
Refers to the ability to run multiple threads in overlapping time periods.

Parallelism:
When multiple threads run on multiple CPUs at the same time.

Advantages of Multithreading
Efficient CPU Utilization:
Multiple threads can utilize the CPU effectively.
Improved Performance:
Tasks like I/O operations and computations can overlap.
Simpler Program Design:
Multithreading simplifies complex tasks like handling user interactions and back-
ground tasks.
Responsive UI:
Applications remain responsive as time-consuming operations run on separate
threads.
Thread Life-cycle:
A thread in Java at any point of time exists in any one of the following states. A thread lies only in
one of the shown states at any instant:

A thread in Java goes through the following states:

New: A thread is created but not started (Thread t = new Thread()).


Runnable: A thread is ready to run and waiting for CPU time.
Running: A thread is executing.
Blocked/Waiting: A thread is waiting for resources or another thread to complete.
Terminated: A thread completes its execution.

New Thread: When a new thread is created, it is in the new state. The thread has not yet started
to run when the thread is in this state. When a thread lies in the new state, its code is yet to be run
and hasn’t started to execute.

Runnable State: A thread that is ready to run is moved to a runnable state. In this state, a thread
might actually be running or it might be ready to run at any instant of time. It is the responsibility of
the thread scheduler to give the thread, time to run.

A multi-threaded program allocates a fixed amount of time to each individual thread. Each and
every thread runs for a short while and then pauses and relinquishes the CPU to another thread
so that other threads can get a chance to run. When this happens, all such threads that are ready
to run, waiting for the CPU and the currently running thread lie in a runnable state.

Blocked: The thread will be in blocked state when it is trying to acquire a lock but currently the
lock is acquired by the other thread. The thread will move from the blocked state to runnable state
when it acquires the lock.
Timed Waiting: A thread lies in a timed waiting state when it calls a method with a time-out param-
eter. A thread lies in this state until the timeout is completed or until a notification is received. For
example, when a thread calls sleep or a conditional wait, it is moved to a timed waiting state.

Terminated State: A thread terminates because of either of the following reasons:


Because it exits normally. This happens when the code of the thread has been entirely executed by
the program.

Thread Class:
The Thread class provides constructors and methods for creating and operating on
threads. The thread extends the Object and implements the Runnable interface.

Runnable interface:
Any class with instances that are intended to be executed by a thread should imple-
ment the Runnable interface. The Runnable interface has only one method, which is
called run().

Important Thread Methods


start():
Starts the thread and invokes the run() method.
Example: thread.start();
run():
The entry point for thread execution. Called internally when start() is invoked.
sleep(long millis):
Causes the thread to pause execution for a specified time.
Example: Thread.sleep(1000);
join():
Waits for the thread to finish execution.
Example: thread.join();
yield():
Hints the thread scheduler to allow other threads to run.
setPriority(int priority):
Sets the thread priority (values range from Thread.MIN_PRIORITY to Thread.MAX_
PRIORITY).
isAlive():
Checks if the thread is still running.
Creating Threads in Java:
Java provides two ways to create threads:

1. By Extending the Thread Class:

ex:
class MyThread extends Thread {
public void run() {
System.out.println(“Thread is running”);
}
}

public class ThreadDemo {


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

2. By Implementing the Runnable Interface:

class MyRunnable implements Runnable {


public void run() {
System.out.println(“Thread is running”);
}
}

public class ThreadDemo {


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

class NewThread implements Runnable {


String name; // name of thread
Thread t;
Output:
NewThread(String threadname) { New thread: Thread[One,5,main]
name = threadname; New thread: Thread[Two,5,main]
New thread: Thread[Three,5,main]
t = new Thread(this, name);
One: 5
System.out.println(“New thread: “ + t); Two: 5
t.start(); // Start the thread Three: 5
} One: 4
Two: 4
public void run() { Three: 4
One: 3
try {
Three: 3
for(int i = 5; i > 0; i--) { Two: 3
System.out.println(name + “: “ + i); One: 2
Thread.sleep(1000); Three: 2
} Two: 2
} catch (InterruptedException e) { One: 1
Three: 1
System.out.println(name + “Interrupted”);
Two: 1
} One exiting.
System.out.println(name + “ exiting.”); Two exiting.
} Three exiting.
} Main thread exiting.

class MultiThreadDemo {
public static void main(String args[]) {
new NewThread(“One”); // start threads
new NewThread(“Two”);
new NewThread(“Three”);
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
System.out.println(“Main thread Interrupted”);
}
System.out.println(“Main thread exiting.”);
}
}
Using isAlive( ) and join( ):
The isAlive( ) method returns true if the thread upon which it is called is still running. It
returns
false otherwise.
While isAlive( ) is occasionally useful, the method that you will more commonly use to
wait for a thread to finish is called join( ), shown here:
final void join( ) throws InterruptedException

class NewThread implements Runnable { System.out.println(“Thread One is alive: “


String name; // name of thread + ob1.t.isAlive());
Thread t; System.out.println(“Thread Two is alive: “
NewThread(String threadname) { + ob2.t.isAlive());
name = threadname; System.out.println(“Thread Three is alive: “
t = new Thread(this, name); + ob3.t.isAlive());
System.out.println(“New thread: “ + t); // wait for threads to finish
t.start(); // Start the thread try {
} System.out.println(“Waiting for threads to finish.”);
// This is the entry point for thread. ob1.t.join();
public void run() { ob2.t.join();
try { ob3.t.join();
for(int i = 5; i > 0; i--) { } catch (InterruptedException e) {
System.out.println(name + “: “ + i); System.out.println(“Main thread Interrupted”);
Thread.sleep(1000); }
} System.out.println(“Thread One is alive: “
} catch (InterruptedException e) { + ob1.t.isAlive());
System.out.println(name + “ interrupted.”); System.out.println(“Thread Two is alive: “
} + ob2.t.isAlive());
System.out.println(name + “ exiting.”); System.out.println(“Thread Three is alive: “
} + ob3.t.isAlive());
} System.out.println(“Main thread exiting.”);
class DemoJoin { }
public static void main(String args[]) { }
NewThread ob1 = new NewThread(“One”);
NewThread ob2 = new NewThread(“Two”);
NewThread ob3 = new NewThread(“Three”);
Thread Priorities in Java:
In Java, threads can have priorities that indicate the relative importance of one thread over
another. Thread priorities help the thread scheduler decide which thread to run next when multiple
threads are eligible for execution. Priorities are set using integers, with higher numbers indicating
higher priorities.

Thread Priority Range


Thread.MIN_PRIORITY (1): Lowest priority.
Thread.NORM_PRIORITY (5): Default priority.
Thread.MAX_PRIORITY (10): Highest priority.
The default priority for a thread is Thread.NORM_PRIORITY, which is 5.

Setting Thread Priorities


The priority of a thread can be set using the setPriority(int priority) method and retrieved using the
getPriority() method.

Example of Setting Thread Priorities

class MyThread extends Thread {


public void run() {
System.out.println(Thread.currentThread().getName() + “ is running with priority “ + Thread.
currentThread().getPriority());
}
}

public class ThreadPriorityDemo {


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

// Setting priorities
t1.setPriority(Thread.MIN_PRIORITY); // Priority 1
t2.setPriority(Thread.NORM_PRIORITY); // Priority 5
t3.setPriority(Thread.MAX_PRIORITY); // Priority 10

// Setting thread names for clarity


t1.setName(“Low Priority Thread”);
t2.setName(“Normal Priority Thread”);
t3.setName(“High Priority Thread”);

// Starting threads
t1.start();
t2.start();
t3.start();
}
}
Synchronization:
When two or more threads need access to a shared resource, they need some way to en-
sure that the resource will be used by only one thread at a time. The process by which this is
achieved is called synchronization.

// This program is not synchronized.


class Callme {
void call(String msg) {
System.out.print(“[“ + msg);
try {
Thread.sleep(1000);
} catch(InterruptedException e) {
System.out.println(“Interrupted”);
}
System.out.println(“]”);
}
}
class Caller implements Runnable {
String msg;
Callme target;
Thread t;
public Caller(Callme targ, String s) {
target = targ;
msg = s;
t = new Thread(this);
t.start();
}
public void run() {
target.call(msg);
}
}
class Synch {
public static void main(String args[]) {
Callme target = new Callme();
Caller ob1 = new Caller(target, “Hello”);
Caller ob2 = new Caller(target, “Synchronized”);
Caller ob3 = new Caller(target, “World”);
// wait for threads to end
try {
ob1.t.join();
ob2.t.join();
Here is the output produced by this program:
ob3.t.join();
Hello[Synchronized[World]
} catch(InterruptedException e) {
]
System.out.println(“Interrupted”);
]
}
}
}
// This program uses a synchronized block.
class Callme {
void call(String msg) {
System.out.print(“[“ + msg);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println(“Interrupted”);
}
System.out.println(“]”);
}
}
class Caller implements Runnable {
String msg;
Callme target;
Thread t;
public Caller(Callme targ, String s) {
target = targ;
msg = s;
t = new Thread(this);
t.start();
}
// synchronize calls to call()
public void run() {
synchronized(target) { // synchronized block
target.call(msg);
}
}
}
class Synch1 {
public static void main(String args[]) {
Callme target = new Callme();
Caller ob1 = new Caller(target, “Hello”);
Caller ob2 = new Caller(target, “Synchronized”);
Caller ob3 = new Caller(target, “World”);
// wait for threads to end
try {
ob1.t.join();
ob2.t.join();
ob3.t.join();
} catch(InterruptedException e) {
System.out.println(“Interrupted”);
}
}
}
Inter-Thread Communication in Java:
Inter-thread communication in Java allows threads to communicate with each oth-
er, ensuring proper coordination when sharing resources or performing tasks. The
primary methods used for inter-thread communication are
wait(), notify(), and notifyAll().

These methods belong to the Object class and must be called from within a syn-
chronized block or method.

wait():
Causes the current thread to wait until another thread invokes notify() or notifyAll()
on the same object.
Releases the lock on the object and pauses the thread.

notify():
Wakes up a single thread that is waiting on the same object’s monitor.

notifyAll():
Wakes up all threads waiting on the object’s monitor.

// A correct implementation of a producer and consumer.


class Q {
int n;
boolean valueSet = false;
synchronized int get() {
while(!valueSet)
try {
wait();
} catch(InterruptedException e) {
System.out.println(“InterruptedException caught”);
}
System.out.println(“Got: “ + n);
valueSet = false;
notify();
return n;
}
synchronized void put(int n) {
while(valueSet)
try {
wait();
}
catch(InterruptedException e) {
{
System.out.println(“InterruptedException caught”);
}
System.out.println(“Got: “ + n);
valueSet = false;
notify();
return n;
}
synchronized void put(int n) {
while(valueSet)
try {
wait();
} catch(InterruptedException e) {
System.out.println(“InterruptedException caught”);
}
this.n = n;
valueSet = true;
System.out.println(“Put: “ + n);
notify();
}
}
class Producer implements Runnable {
Q q;
Producer(Q q) {
this.q = q;
new Thread(this, “Producer”).start();
}
public void run() {
int i = 0;
while(true) {
q.put(i++);
}
}
}
class Consumer implements Runnable {
Q q;
Consumer(Q q) {
this.q = q;
new Thread(this, “Consumer”).start();
}
public void run() {
while(true) {
q.get();
}
}
}
class PCFixed {
public static void main(String args[]) {
Q q = new Q();
new Producer(q);
new Consumer(q);
System.out.println(“Press Control-C to stop.”);
}
}

File Handling in Java


File handling in Java allows reading from and writing to files, enabling programs to store and
retrieve data from disk. The Java I/O package (java.io) and the NIO package (java.nio) provide
various classes and methods for file operations.
1. File Class
Represents file or directory pathnames in an abstract manner.
Does not perform file operations like reading or writing but helps in file metadata and manage-
ment.

import java.io.File;

public class FileExample {


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

if (file.exists()) {
System.out.println(“File exists: “ + file.getName());
System.out.println(“Path: “ + file.getAbsolutePath());
System.out.println(“Writable: “ + file.canWrite());
System.out.println(“Readable: “ + file.canRead());
System.out.println(“File size in bytes: “ + file.length());
} else {
System.out.println(“File does not exist.”);
}
}
}
// Reading data from a file using FileReader
import java.io.*;
class ReadFile
{
public static void main(String[] args) throws IOException
{
// variable declaration
int ch;

// check if File exists or not


FileReader fr=null;
try
{
fr = new FileReader(“text”);
}
catch (FileNotFoundException fe)
{
System.out.println(“File not found”);
}
while ((ch=fr.read())!=-1)
System.out.print((char)ch);
fr.close();
}
}
// Creating a text File using FileWriter
import java.io.*;
class CreateFile
{
public static void main(String[] args) throws IOException
{
// Accept a string
String str = “File Handling in Java using “+
“ FileWriter and FileReader”;

// attach a file to FileWriter


FileWriter fw=new FileWriter(“output.txt”);

// read character wise from string and write


// into FileWriter
for (int i = 0; i < str.length(); i++)
fw.write(str.charAt(i));

System.out.println(“Writing successful”);
//close the file
fw.close();
}
}
Create a File:
To create a file in Java, you can use the createNewFile() method. This method returns a bool-
ean value: true if the file was successfully created, and false if the file already exists. Note that
the method is enclosed in a try...catch block. This is necessary because it throws an IOExcep-
tion if an error occurs (if the file cannot be created for some reason):

import java.io.File; // Import the File class


import java.io.IOException; // Import the IOException class to handle errors

public class CreateFile {


public static void main(String[] args) {
try {
File myObj = new File(“filename.txt”);
if (myObj.createNewFile()) {
System.out.println(“File created: “ + myObj.getName());
} else {
System.out.println(“File already exists.”);
}
} catch (IOException e) {
System.out.println(“An error occurred.”);
e.printStackTrace();
} }}
Read a File:
In the following example, we use the Scanner class to read the contents of
the text file we created in the previous chapter: import java.io.File; // Import the
File class
import java.io.FileNotFoundException; // Import this class to handle errors
import java.util.Scanner; // Import the Scanner class to read text files

public class ReadFile {


public static void main(String[] args) {
try {
File myObj = new File(“filename.txt”);
Scanner myReader = new Scanner(myObj);
while (myReader.hasNextLine()) {
String data = myReader.nextLine();
System.out.println(data);
}
myReader.close();
} catch (FileNotFoundException e) {
System.out.println(“An error occurred.”);
e.printStackTrace();
} }}
Write To a File:

import java.io.FileWriter; // Import the FileWriter class


import java.io.IOException; // Import the IOException class to handle errors

public class WriteToFile {


public static void main(String[] args) {
try {
FileWriter myWriter = new FileWriter(“filename.txt”);
myWriter.write(“Files in Java might be tricky, but it is fun enough!”);
myWriter.close();
System.out.println(“Successfully wrote to the file.”);
} catch (IOException e) {
System.out.println(“An error occurred.”);
e.printStackTrace();
}
}
}
Random access file:
Java.io.RandomAccessFile Class provides a way to random access files using
reading and writing operations. It works like an array of byte storted in the File.

read() : java.io.RandomAccessFile.read() reads byte of data from file. The byte is


returned as an integer in the range 0-255.

read(byte[] b) java.io.RandomAccessFile.read(byte[] b) reads bytes upto b.length


from the buffer.

readBoolean() : java.io.RandomAccessFile.readBoolean() reads a boolean from the file.


readByte() : java.io.RandomAccessFile.readByte() reads a signed eight-bit value from file, start
reading from the File Pointer.
readChar() : java.io.RandomAccessFile.readChar() reads a character from the file, start reading
from the File Pointer.
readDouble() : java.io.RandomAccessFile.readDouble() reads a double value from the file, start
reading from the File Pointer.
readFloat() : java.io.RandomAccessFile.readFloat() reads a float value from the file, start reading
from the File Pointer.
readInt() : java.io.RandomAccessFile.readInt() reads a signed 4 bytes integer from the file, start
reading from the File Pointer.
Collections in Java
The Collections Framework in Java is a unified architecture for storing and manipulating groups
of objects.
It provides a set of classes and interfaces for data structures such as lists, sets, queues, and
maps.

The framework is part of the java.util package and is widely used for handling dynamic and com-
plex data structures.

Key Features of Collections Framework:

Dynamic Size: Unlike arrays, collections can grow or shrink dynamically.


Standard Interfaces: Provides a set of well-defined interfaces (e.g., List, Set, Map).
Built-in Algorithms: Includes utility methods for sorting, searching, and manipulating data (Col-
lections class).
Type Safety: Supports generics for compile-time type checking.
List Collection in Java:
A List is an ordered collection in Java that allows duplicate elements. It is part of the Java Collections
Framework and implements the java.util.List interface.

Characteristics of List:
Order:Elements are maintained in the order they are added (insertion order).
Indexing:Each element is associated with an index, starting from 0.
Elements can be accessed, updated, or removed using their indices.
Allows Duplicates:A List can contain duplicate elements.
Resizing:Automatically resizes when adding or removing elements.

Commonly Used List Implementations:

ArrayList : Backed by a dynamic array; fast random access but slower insert/delete.
LinkedList: Backed by a doubly-linked list; better for frequent insertions/deletions.
Vector : Synchronized; legacy class, slower compared to ArrayList.
Stack: Subclass of Vector; follows LIFO (Last In, First Out).
List Interface Methods:
Method Description
void add(E element) Adds the specified element to the list.
void add(int index, E element) Inserts the element at the specified index.
E get(int index) Returns the element at the specified index.
E set(int index, E element) Replaces the element at the specified index.
E remove(int index) Removes the element at the specified index.
boolean remove(Object o) Removes the first occurrence of the specified element.
int size() Returns the number of elements in the list.
boolean contains(Object o) Checks if the list contains the specified element.
int indexOf(Object o) Returns the index of the first occurrence of the element.
void clear() Removes all elements from the list.
Iterator<E> iterator() Returns an iterator for the list.

ArrayList in Java:
The ArrayList is a resizable array implementation of the List interface in Java. It is part of the
Java Collections Framework and resides in the java.util package.

Unlike regular arrays, an ArrayList can grow or shrink dynamically as elements are added or re-
moved.

Features of ArrayList
Dynamic Size:
Automatically resizes itself when elements are added or removed.
Indexed Access:
Elements can be accessed using an index (similar to arrays).
Allows Duplicates:
Supports duplicate elements.
Maintains Insertion Order:
Elements are stored in the order they are added.
Non-Synchronized:
Not thread-safe. Use Collections.synchronizedList for thread safety.
Generics Support:
Ensures type safety during compile time.

import java.util.ArrayList;

public class ArrayListExample {


public static void main(String[] args) {
// Create an ArrayList of Strings
ArrayList<String> fruits = new ArrayList<>();

// Add elements
fruits.add(“Apple”);
fruits.add(“Banana”);
fruits.add(“Cherry”);
// Access elements
System.out.println(“First fruit: “ + fruits.get(0));

// Modify element
fruits.set(1, “Blueberry”);

// Remove an element
fruits.remove(“Apple”);

// Iterate over the list


System.out.println(“Fruits:”);
for (String fruit : fruits) {
System.out.println(fruit);
}

// Check size
System.out.println(“Size of list: “ + fruits.size());
}
}

First fruit: Apple


Fruits:
Blueberry
Cherry
Size of list: 2

Example: Using Generics


Generics provide type safety, ensuring that only specified types of elements can be added to the
list.

import java.util.ArrayList;

public class GenericsExample {


public static void main(String[] args) {
// Create a type-safe ArrayList of Integers
ArrayList<Integer> numbers = new ArrayList<>();

// Add elements
numbers.add(10);
numbers.add(20);
numbers.add(30);

// Iterate and print


for (int num : numbers) {
System.out.println(num);
}
}
}
Sorting an ArrayList:
You can use Collections.sort to sort an ArrayList in ascending or descending order.

import java.util.ArrayList;
import java.util.Collections;

public class SortingExample {


public static void main(String[] args) {
ArrayList<Integer> numbers = new ArrayList<>();
numbers.add(5);
numbers.add(3);
numbers.add(8);

// Sort in ascending order


Collections.sort(numbers);
System.out.println(“Ascending: “ + numbers);

// Sort in descending order


Collections.sort(numbers, Collections.reverseOrder());
System.out.println(“Descending: “ + numbers);
}
}
Output:
Ascending: [3, 5, 8]
Descending: [8, 5, 3]

Converting ArrayList to Array:


You can convert an ArrayList to an array using the toArray() method.

import java.util.ArrayList;

public class ConvertToArray {


public static void main(String[] args) {
ArrayList<String> colors = new ArrayList<>();
colors.add(“Red”);
colors.add(“Green”);
colors.add(“Blue”);

// Convert to array
String[] colorArray = colors.toArray(new String[0]);

// Print array
for (String color : colorArray) {
System.out.println(color);
}
}
}
Advantages of ArrayList
Dynamic Size: Automaticall:y resizes as elements are added or removed.
Random Access: Provides O(1) time complexity for element access.
Flexible: Can contain duplicates and allows null values.

LinkedList in Java:
The LinkedList is a part of the Java Collections Framework and implements the List, Deque, and
Queue interfaces. It is a doubly-linked list, making it ideal for scenarios where frequent insertions and
deletions occur.

Doubly-Linked List:
Each element (node) contains a reference to the previous and next element.
Dynamic Size:
Automatically resizes as elements are added or removed.
Sequential Access:
Best suited for sequential access of elements.
Supports Null Elements:
Can store null values.
Implements Multiple Interfaces:
Supports list, queue, and deque operations.
Allows Duplicates:
Duplicate elements are permitted.
import java.util.LinkedList;

public class LinkedListExample {


public static void main(String[] args) {
// Create a LinkedList of Strings
LinkedList<String> animals = new LinkedList<>();

// Add elements
animals.add(“Dog”);
animals.add(“Cat”);
animals.add(“Horse”);
Output:
// Access elements First animal: Dog
System.out.println(“First animal: “ + animals.get(0)); Animals in the list:
Dog
// Modify an element
Lion
animals.set(1, “Lion”);
Size of the list: 2
// Remove an element
animals.remove(“Horse”);

// Iterate over the list


System.out.println(“Animals in the list:”);
for (String animal : animals) {
System.out.println(animal);
}
// Check size
System.out.println(“Size of the list: “ + animals.size());
}
}
LinkedList Using as a Queue:

The LinkedList can be used as a queue due to its support for the Queue and Deque interfaces.

import java.util.LinkedList;
import java.util.Queue;

public class QueueExample {


public static void main(String[] args) {
Queue<String> queue = new LinkedList<>();

// Add elements to the queue


queue.add(“A”);
queue.add(“B”);
queue.add(“C”);

// Remove and retrieve elements


System.out.println(“Removed: “ + queue.poll()); // Removes and returns the head
System.out.println(“Head of the queue: “ + queue.peek()); // Returns the head without removing

// Iterate over the queue


System.out.println(“Remaining elements:”);
for (String element : queue) {
System.out.println(element);
}
}
}
output:
Removed: A
Head of the queue: B
Remaining elements:
B
C
Using as a Stack
LinkedList can also be used as a stack by leveraging the Deque methods.

import java.util.LinkedList;

public class StackExample {


public static void main(String[] args) {
LinkedList<Integer> stack = new LinkedList<>();

// Push elements onto the stack


stack.push(10);
stack.push(20);
stack.push(30);

// Pop elements from the stack


System.out.println(“Popped: “ + stack.pop());

// Peek at the top element


System.out.println(“Top element: “ + stack.peek());

// Iterate through the stack


System.out.println(“Remaining stack:”);
for (int num : stack) {
System.out.println(num);
}
}
}

Popped: 30
Top element: 20
Remaining stack:
20
10
Set Interface in Java:
The Set interface is a part of the Java Collections Framework and is defined in the java.util package. A
Set represents a collection of unique elements, meaning it does not allow duplicate values.

Key Characteristics of Set

No Duplicates: Ensures that all elements in the collection are unique.


No Indexing: Does not maintain or provide access by index.
Implements Collection Interface: Inherits methods from the Collection interface.
Different Implementations:
Different types of Set implementations provide unique features, like maintaining order or offering con-
stant-time performance.




HashSet in Java:
The HashSet is a part of the Java Collections Framework and implements the Set interface. It
is a collection that uses a hash table for storage, making it efficient for operations like adding, remov-
ing, and searching elements.

Key Characteristics of HashSet


No Duplicates:
Ensures that all elements in the collection are unique.
No Order Guarantee:
Does not maintain any specific order of elements (neither insertion order nor sorting).
Null Element:
Allows at most one null value.
Backed by a Hash Table:
Provides constant-time performance (O(1)) for basic operations (add, remove, contains), assuming
the hash function disperses elements properly.
Not Synchronized:
Not thread-safe; requires external synchronization for multithreaded environments.
Implements Serializable and Cloneable:
Can be serialized and cloned.
import java.util.HashSet;

public class HashSetExample {


public static void main(String[] args) {
// Create a HashSet
HashSet<String> set = new HashSet<>();

// Add elements
set.add(“Apple”);
set.add(“Banana”);
set.add(“Cherry”);
set.add(“Apple”); // Duplicate element, ignored

// Display the set


System.out.println(“HashSet: “ + set);

// Check if an element exists


System.out.println(“Contains ‘Banana’: “ + set.contains(“Banana”));

// Remove an element
set.remove(“Cherry”);

// Iterate through the set


System.out.println(“Elements in HashSet:”);
for (String element : set) {
System.out.println(element);
}
}
}
Output:

yaml
Copy code
HashSet: [Banana, Apple, Cherry]
Contains ‘Banana’: true
Elements in HashSet:
Banana
Apple

Advantages of HashSet:
Fast Operations:
Provides constant-time performance for add, remove, and contains operations.
No Duplicates:
Automatically ensures that elements are unique.
Flexible:
Allows a single null value and can store heterogeneous objects.
Disadvantages of HashSet:
No Order:Does not maintain insertion order or any natural sorting order.
Not Thread-Safe:Requires manual synchronization if accessed by multiple threads.

LinkedHashSet:
In Java, a LinkedHashSet is part of the Java Collections Framework and is located in the java.util
package. It is an implementation of the Set interface, combining the characteristics of a HashSet (no
duplicate elements) and a linked list (maintains insertion order).

Key Points About LinkedHashSet:

Maintains Insertion Order:


Unlike HashSet, which does not guarantee order, LinkedHashSet preserves the order in which ele-
ments are added.

No Duplicates:
Like all Set implementations, it does not allow duplicate elements.

Implements Set Interface:


Supports all methods of the Set interface, such as add, remove, contains, and size.

Performance:
Provides constant time (O(1)) for basic operations like add, remove, and contains, similar to
HashSet.

Underlying Structure:
It uses a hash table and a doubly-linked list to store its elements.

import java.util.LinkedHashSet;

public class Main {


public static void main(String[] args) {
// Create a LinkedHashSet
LinkedHashSet<String> set = new LinkedHashSet<>();

// Adding elements
set.add(“Apple”);
set.add(“Banana”);
set.add(“Cherry”);
set.add(“Apple”); // Duplicate, won’t be added

// Iterating through the LinkedHashSet


for (String fruit : set) {
System.out.println(fruit);
}
// Check if an element exists
System.out.println(“Contains ‘Banana’: “ + set.contains(“Banana”));

// Remove an element
set.remove(“Banana”);
System.out.println(“After removing ‘Banana’: “ + set);

// Size of the set


System.out.println(“Size of the set: “ + set.size());
}
}

o/p :

Apple
Banana
Cherry
Contains ‘Banana’: true
After removing ‘Banana’: [Apple, Cherry]
Size of the set: 2

Methods in LinkedHashSet:

Some of the key methods include:

add(E e) – Adds the specified element if it is not already present.


remove(Object o) – Removes the specified element from the set.
contains(Object o) – Checks if the set contains the specified element.
size() – Returns the number of elements in the set.
clear() – Removes all elements from the set.
isEmpty() – Checks if the set is empty.

TreeSet:
A TreeSet is another data structure in Java’s Collections Framework. It is part of the java.
util package and implements the Set interface. A TreeSet is a specialized Set that uses a binary
search tree (specifically, a Red-Black Tree) under the hood to store elements.

Key Features of TreeSet:


Sorted Order:
Unlike HashSet or LinkedHashSet, a TreeSet keeps its elements sorted in natural order (e.g.,
numbers in ascending order or strings in alphabetical order) or according to a custom compara-
tor.

No Duplicates:
Like all Set implementations, TreeSet does not allow duplicate elements.
Implements NavigableSet
Implements NavigableSet:
A TreeSet supports navigation methods such as lower(), higher(), floor(), and ceiling().
Performance:
Operations such as add, remove, and contains take O(log n) time because the tree is kept balanced.
Comparator Support:
You can provide a custom comparator at the time of creation for custom sorting logic.
Example:
import java.util.TreeSet;

public class Main {


public static void main(String[] args) {
// Create a TreeSet of integers
TreeSet<Integer> numbers = new TreeSet<>();

// Adding elements
numbers.add(10);
numbers.add(20);
numbers.add(5);
numbers.add(15);

// Duplicate elements are ignored


numbers.add(10);

// Print elements (sorted order)


System.out.println(“TreeSet: “ + numbers);

// Accessing elements
System.out.println(“First Element: “ + numbers.first());
System.out.println(“Last Element: “ + numbers.last());

// Navigating
System.out.println(“Element less than 15: “ + numbers.lower(15));
System.out.println(“Element greater than 15: “ + numbers.higher(15));

// Removing an element
numbers.remove(10);
System.out.println(“After removing 10: “ + numbers); Output Example:
TreeSet: [5, 10, 15, 20]
First Element: 5
// Iterating through the TreeSet Last Element: 20
for (Integer number : numbers) { Element less than 15: 10
System.out.println(number); Element greater than 15: 20
} After removing 10: [5, 15, 20]
} 5
} 15
20
Methods in TreeSet:

Here are some key methods provided by TreeSet:

add(E e) : Adds the specified element to the set.


remove(Object o): Removes the specified element from the set.
first() : Returns the first (lowest) element.
last() : Returns the last (highest) element.
lower(E e) : Returns the greatest element strictly less than e.
higher(E e) : Returns the smallest element strictly greater than e.
floor(E e): Returns the greatest element less than or equal to e.
ceiling(E e) : Returns the smallest element greater than or equal to e.
pollFirst(): Removes and returns the first element.
pollLast(): Removes and returns the last element.
size() : Returns the number of elements.
clear(): Removes all elements from the set.

import java.util.TreeSet;

public class Main {


public static void main(String[] args) {
// Create a TreeSet and add elements
TreeSet<Integer> numbers = new TreeSet<>();
numbers.add(2);
numbers.add(5);
numbers.add(8);
numbers.add(3);
numbers.add(10);

// Use headSet() to find numbers less than 7


TreeSet<Integer> lessThanSeven = new TreeSet<>(numbers.headSet(7));

// Print the result


System.out.println(“Numbers less than 7: “ + lessThanSeven);
}
}
Queues:
In Java, a queue is a data structure that follows the First-In-First-Out (FIFO) principle, meaning the
first element added to the queue is the first one to be removed. Java provides multiple implementa-
tions of queues as part of the Collections Framework, making it versatile and suitable for various use
cases.

Types of Queues in Java:


The Queue interface is part of the java.util package.
Its main implementations include:

LinkedList: A general-purpose implementation of the Queue interface.


PriorityQueue: A queue that orders its elements based on their natural ordering or a
provided comparator.
ArrayDeque: A resizable array-based implementation, used as both a queue and a
deque (double-ended queue).
ConcurrentLinkedQueue:A thread-safe, high-performance queue.
BlockingQueue: Used in multithreading, where operations like insertion and removal block
until conditions are met.

Key Methods of the Queue Interface


Method Description
add(E e): Inserts the specified element into the queue (throws exception if capacity is reached).
offer(E e): Inserts the specified element into the queue (returns false if capacity is reached).
remove(): Removes and returns the head of the queue (throws exception if empty).
poll(): Removes and returns the head of the queue, or returns null if the queue is empty.
element(): Retrieves the head of the queue without removing it (throws exception if empty).
peek() : Retrieves the head of the queue without removing it, or returns null if the queue is
empty.

EXAMPLE:
import java.util.LinkedList;
import java.util.Queue;

public class Main {


public static void main(String[] args) {
// Create a queue using LinkedList
Queue<Integer> queue = new LinkedList<>();

// Add elements to the queue


queue.add(10);
queue.add(20);
queue.add(30);

// Peek at the head of the queue


System.out.println(“Head of queue: “ + queue.peek());

// Remove elements from the queue


System.out.println(“Removed: “ + queue.poll());
System.out.println(“Removed: “ + queue.poll());

// Check the remaining elements


System.out.println(“Remaining queue: “ + queue);
}
}
O/P:
Head of queue: 10
Removed: 10
Removed: 20
Remaining queue: [30]

Using PriorityQueue:
A PriorityQueue orders elements based on their natural order or a custom comparator.

import java.util.PriorityQueue;

public class Main {


public static void main(String[] args) {
// Create a priority queue
PriorityQueue<Integer> pq = new PriorityQueue<>();

// Add elements
pq.add(20);
pq.add(10);
pq.add(30);

// Retrieve and remove elements


while (!pq.isEmpty()) {
System.out.println(“Polled: “ + pq.poll());
}
}
}
Output:

makefile
Copy code
Polled: 10
Polled: 20
Polled: 30
Using ArrayDeque:
ArrayDeque is often faster than LinkedList and can act as both a queue and a deque.

import java.util.ArrayDeque;
import java.util.Queue;

public class Main {


public static void main(String[] args) {
// Create an ArrayDeque
Queue<String> queue = new ArrayDeque<>();

// Add elements
queue.offer(“Alice”);
queue.offer(“Bob”);
queue.offer(“Charlie”);

// Process the queue


while (!queue.isEmpty()) {
System.out.println(“Processed: “ + queue.poll());
}
}
}
Processed: Alice
Processed: Bob
Processed: Charlie
Maps :
In Java, Maps are part of the Collections Framework and are used to store key-value pairs. Unlike
other collections like List or Set, which hold only values, a Map associates a unique key with each
value. This makes it ideal for scenarios where you need to look up data quickly using a key.

Key Features of Maps

Key-Value Pair:

A Map stores data as key-value pairs, where keys are unique, and each key maps to exactly one
value.
No Duplicate Keys:
Keys in a Map must be unique. Duplicate keys will overwrite the existing value for that key.

Null Values and Keys:


Depending on the implementation, Map can allow one null key (e.g., HashMap) and multiple null
values.

Common Operations:
Retrieve, insert, update, or delete key-value pairs.
Common Map Implementations in Java

HashMap: Fast, unsorted, unordered. Allows one null key and multi-
ple null values.
LinkedHashMap : Maintains insertion order or access order.
TreeMap : Sorted by natural order of keys or by a custom comparat-
or.
Hashtable : Thread-safe but considered legacy. Does not allow null
keys or values.
ConcurrentHashMap: Thread-safe implementation for high-performance concur-
rent access.

Hashmap:
The HashMap is one of the most commonly used implementations of the Map
interface in Java. It is part of the Java Collections Framework and is used to store
key-value pairs. HashMap is based on the hashing principle, allowing for efficient
insertion, deletion, and lookup operations.
Key Features of HashMap
Key-Value Pair:
Stores elements as key-value pairs where keys are unique, and each key is asso-
ciated with exactly one value.

Allows Nulls:
Allows one null key and multiple null values.

No Order:
Does not maintain the order of elements. If order matters, use LinkedHashMap.

Performance:
Provides average time complexity of O(1) for basic operations like get and put.

Hashing:
Uses a hash table to store elements, with a hash function to calculate the hash
code of keys.

HashMap Declaration

To declare a HashMap:

HashMap<K, V> map = new HashMap<>();

Here:
K is the type of keys.
V is the type of values.

Example:
HashMap<String, Integer> map = new HashMap<>();
import java.util.HashMap;
public class Main {
public static void main(String[] args) {
// Create a HashMap
HashMap<String, Integer> map = new HashMap<>();
// Add key-value pairs
map.put(“Alice”, 30);
map.put(“Bob”, 25);
map.put(“Charlie”, 35);
// Retrieve a value
System.out.println(“Alice’s age: “ + map.get(“Alice”));
// Check if a key exists
System.out.println(“Contains Bob? “ + map.containsKey(“Bob”));
// Remove a key
map.remove(“Charlie”);
// Iterate through the map
for (HashMap.Entry<String, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + “: “ + entry.getValue());
} }}
Output:
Alice’s age: 30
Contains Bob? true
Alice: 30
Bob: 25
Iterating Through a HashMap

Using entrySet:

for (Map.Entry<String, Integer> entry : map.entrySet()) {


System.out.println(entry.getKey() + “: “ + entry.getValue());
}
Using keySet:

for (String key : map.keySet()) {


System.out.println(key + “: “ + map.get(key));
}
Using values:

for (Integer value : map.values()) {


System.out.println(“Value: “ + value);
}
Handling Collisions in HashMap:
HashMap uses buckets to store entries. Each key’s hash code deter-
mines the bucket where the key-value pair will be stored.

Collisions occur when multiple keys have the same hash code. In such
cases, HashMap uses a linked list or a balanced tree (since Java 8) to
store entries in the same bucket.

HashMap allows: One null key. Multiple null values.


Example:

HashMap<String, String> map = new HashMap<>();


map.put(null, “Value1”);
map.put(“Key1”, null);
map.put(“Key2”, null);

System.out.println(map);
Output:

{null=Value1, Key1=null, Key2=null}


Advantages of HashMap:
Fast: Offers constant time for insertion and retrieval (on average).
Flexible: Allows null keys and values.
Dynamic: Automatically resizes itself when needed.
Disadvantages of HashMap
No Order: Does not guarantee the order of elements.
Thread-Safety: Not synchronized. For thread-safe operations, use Concurren-
tHashMap.

TreeMap:
The TreeMap is a part of Java’s java.util package and implements the Map inter-
face.
It stores key-value pairs in a sorted order based on the natural ordering of the keys
or a custom comparator provided at the time of creation. Internally,
TreeMap uses a Red-Black Tree, which ensures that the map is always balanced,
providing O(log n) time complexity for most operations.
Key Features of TreeMap
Sorted Order:Keys are sorted in their natural order (ascending) or according to a
custom comparator.
No Null Keys: Does not allow null keys but allows multiple null values.
NavigableMap Interface:Extends NavigableMap, providing methods for navigation
(e.g., floorEntry, ceilingEntry).
Performance:Operations like get, put, remove, etc., have a time complexity of
O(log n).
Thread Safety:Not thread-safe. Use Collections.synchronizedMap or Concur-
rentSkipListMap for concurrent operations.
TreeMap Declaration:

TreeMap<K, V> map = new TreeMap<>();


Here:
K is the type of keys.
V is the type of values.
Example:
TreeMap<String, Integer> map = new TreeMap<>();

import java.util.TreeMap;
public class Main {
public static void main(String[] args) {
// Create a TreeMap
TreeMap<String, Integer> map = new TreeMap<>();

// Add key-value pairs


map.put(“Apple”, 50);
map.put(“Banana”, 30);
map.put(“Cherry”, 20);

// Print the TreeMap (sorted by key)


System.out.println(“TreeMap: “ + map);

// Retrieve a value
System.out.println(“Value for ‘Banana’: “ + map.get(“Banana”));

// Remove a key
map.remove(“Cherry”);

// Iterate through the TreeMap


for (String key : map.keySet()) {
System.out.println(key + “: “ + map.get(key));
}
}
}

Output:
TreeMap: {Apple=50, Banana=30, Cherry=20}
Value for ‘Banana’: 30
Apple: 50
Banana: 30
Submaps with TreeMap
HeadMap and TailMap

import java.util.TreeMap;

public class Main {


public static void main(String[] args) {
TreeMap<Integer, String> map = new TreeMap<>();

// Add key-value pairs


map.put(10, “Ten”);
map.put(20, “Twenty”);
map.put(30, “Thirty”);

// Create a headMap
System.out.println(“HeadMap (keys < 20): “ + map.headMap(20));

// Create a tailMap
System.out.println(“TailMap (keys >= 20): “ + map.tailMap(20));
}
}
Output:
HeadMap (keys < 20): {10=Ten}
TailMap (keys >= 20): {20=Twenty, 30=Thirty}

import java.util.TreeMap;
import java.util.Comparator;
public class Main {
public static void main(String[] args) {
// Custom Comparator for descending order
TreeMap<String, Integer> map = new TreeMap<>(Comparator.reverseOrder());
map.put(“Apple”, 50);
map.put(“Banana”, 30);
map.put(“Cherry”, 20);

// Print the TreeMap


System.out.println(“TreeMap with custom sorting: “ + map);
}
}

o/p: TreeMap with custom sorting: {Cherry=20, Banana=30, Apple=50}


LinkedHashMap:
The LinkedHashMap is a part of Java’s java.util package and implements the
Map interface. It extends HashMap and maintains a doubly-linked list across its
entries to preserve the insertion order or access order, depending on the configu-
ration.
Key Features of LinkedHashMap:
Preserves Order:By default, it maintains the insertion order of the entries.
Can also be configured to maintain access order, where entries are reordered
when accessed.
Allows Nulls:Allows one null key and multiple null values, similar to HashMap.
Performance:Provides similar performance to HashMap for most operations (O(1)
average for get and put).
Not Thread-Safe:Not synchronized. Use Collections.synchronizedMap for thread-
safe operations.

LinkedHashMap Declaration:

To declare a LinkedHashMap:

LinkedHashMap<K, V> map = new LinkedHashMap<>();


Here:

K is the type of keys.


V is the type of values.
Example:

LinkedHashMap<String, Integer> map = new LinkedHashMap<>();


import java.util.LinkedHashMap;

public class Main {


public static void main(String[] args) {
// Create a LinkedHashMap
LinkedHashMap<String, Integer> map = new LinkedHashMap<>();

// Add key-value pairs


map.put(“Apple”, 50);
map.put(“Banana”, 30);
map.put(“Cherry”, 20);

// Print the LinkedHashMap (maintains insertion order)


System.out.println(“LinkedHashMap: “ + map);

// Retrieve a value
System.out.println(“Value for ‘Banana’: “ + map.get(“Banana”));

// Remove a key
map.remove(“Cherry”);
// Iterate through the LinkedHashMap
for (String key : map.keySet()) {
System.out.println(key + “: “ + map.get(key));
}
}
Iterable:
In Java, the Iterable interface is part of the java.lang package and represents a collection
of elements that can be iterated one at a time.
It is the root interface for all collection classes in Java, providing the foundation for itera-
tion using the for-each loop.

Implemented by most collection classes (e.g., List, Set, Queue).

Iterator Support:
Provides an Iterator object to traverse the elements in a collection.

Enhanced For-Loop:
Enables the use of the for-each loop to iterate over the collection.

Functional Programming:
Since Java 8, includes the forEach method to perform actions on each element of the collection
using a lambda expression or method reference.
Using Iterable
1. Iteration Using Iterator:
The iterator() method provides an Iterator object to traverse the collection ele-
ments.

import java.util.ArrayList;
import java.util.Iterator;

public class Main {


public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add(“Apple”);
list.add(“Banana”);
list.add(“Cherry”);

// Using an Iterator
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
} } }
Output:
Apple
Banana
Cherry
Iteration Using for-each Loop:
The for-each loop internally uses the Iterator provided by the Iterable in-
terface.

Example:

import java.util.ArrayList;

public class Main {


public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add(“Apple”);
list.add(“Banana”);
list.add(“Cherry”);

// Using for-each loop


for (String item : list) {
System.out.println(item);
}
}
}
output:
Apple
Banana
Cherry
Unit V

JavaFX Overview:
JavaFX is a powerful framework for building rich client applications in Java. It
is a successor to Swing and provides modern UI components, multimedia support,
and features for creating graphical user interfaces (GUIs).
Key Features of JavaFX:
Rich UI Controls:
Offers a wide range of built-in components like buttons, tables, trees, charts,
menus, and more.
FXML:
A declarative XML-based language for designing GUIs, allowing separation of UI
design from application logic.
CSS Support:
Provides a CSS-like styling mechanism for customizing the appearance of the UI.
Multimedia:
Supports audio and video playback.
Hardware Acceleration:
Uses the Graphics Processing Unit (GPU) for rendering, improving performance.
Web Integration:
Includes a WebView component for embedding web pages.
Scene Graph:
JavaFX applications are built on a scene graph architecture, enabling hierarchical
organization of UI components.

Structure of a JavaFX Application:

A JavaFX application consists of:

Stage: Represents the main window of the application.


Scene: Represents the content inside the stage.
Node: A visual component in the scene graph.
Hello World Example:

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

public class HelloWorld extends Application {


@Override
public void start(Stage primaryStage) {
// Create a Button
Button btn = new Button(“Click Me”);

// Set an action for the button


btn.setOnAction(event -> System.out.println(“Hello, JavaFX!”));

// Create a layout and add the button


StackPane root = new StackPane(btn);

// Create a scene
Scene scene = new Scene(root, 300, 200);

// Configure the stage


primaryStage.setTitle(“Hello JavaFX”);
primaryStage.setScene(scene);
primaryStage.show();
}

public static void main(String[] args) {


launch(args); // Launch the JavaFX application
}
}
Explanation:

Application Class:
The entry point for JavaFX applications. It contains the start method
where the UI is initialized.

Stage: Represents the main window. It is created automatically and


passed to the start method.

Scene: Contains all the UI elements.


Node: Represents a UI component (e.g., Button, TextField, etc.).

Common JavaFX Layouts:

JavaFX provides layouts to arrange UI components in a scene:

StackPane: Stacks all children on top of each other.


HBox: Arranges children in a horizontal row.
VBox: Arranges children in a vertical column.
BorderPane: Divides the layout into top, bottom, left, right, center.
GridPane: Aligns children in a grid format (rows and columns).
AnchorPane: Anchors children to specific positions in the pane.

Example with Layouts

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 LayoutExample extends Application {
@Override
public void start(Stage primaryStage) {
// Create buttons
Button btn1 = new Button(“Button 1”);
Button btn2 = new Button(“Button 2”);
Button btn3 = new Button(“Button 3”);

// HBox Layout
HBox hBox = new HBox(10, btn1, btn2);

// VBox Layout
VBox vBox = new VBox(10, hBox, btn3);

// Create a scene
Scene scene = new Scene(vBox, 300, 200);

// Configure the stage


primaryStage.setTitle(“JavaFX Layout Example”);
primaryStage.setScene(scene);
primaryStage.show();
}

public static void main(String[] args) {


launch(args);
}
}
FXML:

FXML is an XML-based language for defining the UI layout.

FXML File (layout.fxml)

<?xml version=”1.0” encoding=”UTF-8”?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.VBox?>

<VBox spacing=”10” xmlns=”http://javafx.com/javafx/8.0.0” xmlns:fx=”http://javafx.com/fxml/1”>


<Button text=”Button 1” />
<Button text=”Button 2” />
<Button text=”Button 3” />
</VBox>

Java file:
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class FXMLExample extends Application {


@Override
public void start(Stage primaryStage) throws Exception {
// Load FXML file
Parent root = FXMLLoader.load(getClass().getResource(“layout.fxml”));

// Create and configure the scene


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

primaryStage.setTitle(“FXML Example”);
primaryStage.setScene(scene);
primaryStage.show();
}

public static void main(String[] args) {


launch(args);
}
}
Styling with CSS:

You can style JavaFX applications using CSS.

CSS File (styles.css)


.button {
-fx-background-color: #4CAF50;
-fx-text-fill: white;
-fx-font-size: 14px;
-fx-padding: 10;
}
Java File:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class CSSExample extends Application {


@Override
public void start(Stage primaryStage) {
Button btn = new Button(“Styled Button”);

StackPane root = new StackPane(btn);


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

// Apply CSS
scene.getStylesheets().add(getClass().getResource(“styles.css”).toExternal-
Form());

primaryStage.setTitle(“CSS Example”);
primaryStage.setScene(scene);
primaryStage.show();
}

public static void main(String[] args) {


launch(args);
}
}
JavaFX Scene Builder:
JavaFX Scene Builder is a graphical user interface (GUI) tool that enables
developers to design JavaFX application interfaces visually. It allows you to drag
and drop UI components to build a scene graph without writing code manually.
The resulting layout is saved in FXML, which can then be integrated into your
Java application.
Key Features of Scene Builder
Drag-and-Drop Interface:
Simplifies the creation of JavaFX layouts by allowing users to visually design the
UI.
FXML Integration:
Generates FXML code that can be loaded into your JavaFX application.
CSS Styling:
Supports applying CSS styles to the UI elements directly within the tool.
Component Properties:
Provides a property inspector to modify attributes like size, alignment, color, etc.
Custom Components:
Allows adding custom controls and third-party libraries.
Preview:
Lets you preview your application interface in real time.

Downloading and Installing Scene Builder:


Download:

Scene Builder can be downloaded from Gluon Scene Builder.


Installation:

After downloading the appropriate version for your operating system, follow the
installation instructions provided.
Integration with IDEs:

Scene Builder can be integrated with popular IDEs like:


IntelliJ IDEA
Eclipse
NetBeans
Getting Started with Scene Builder:
1. Creating a New FXML File:
Launch Scene Builder.
Click File → New.
Drag UI components (e.g., Button, Label, TextField) from the Library
pane to the Content Panel.
2. Modifying Component Properties
Select a component in the layout.
Use the Inspector Pane to modify properties like text, layout, and style.
3. Saving the Layout
Save the layout as an .fxml file (e.g., layout.fxml).

Using FXML in Java:


Once you have designed the UI in Scene Builder, you can use the gen-
erated FXML file in your JavaFX application.

Example:
FXML File (layout.fxml)

<?xml version=”1.0” encoding=”UTF-8”?>


<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.VBox?>

<VBox alignment=”CENTER” spacing=”10” xmlns=”http://javafx.com/ja-


vafx/8.0.0” xmlns:fx=”http://javafx.com/fxml/1”>
<Button text=”Button 1” />
<Button text=”Button 2” />
</VBox>
Java File (Main.java):

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Main extends Application {


@Override
public void start(Stage primaryStage) throws Exception {
// Load the FXML file
Parent root = FXMLLoader.load(getClass().getResource(“layout.fxml”));

// Create and configure the scene


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

primaryStage.setTitle(“JavaFX Scene Builder Example”);


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

public static void main(String[] args) {


launch(args);
}
}

Integrating Scene Builder with IntelliJ IDEA


Install Scene Builder:

Download and install Scene Builder as described above.


Link Scene Builder to IntelliJ:

Go to File → Settings → Languages & Frameworks → JavaFX.


Set the Path to SceneBuilder to the installation directory.
Create an FXML File:

Right-click on your project → New → FXML File.


Open the FXML file in Scene Builder by right-clicking it and selecting Open in
SceneBuilder.
Styling Scene Builder Projects with CSS:
You can style your JavaFX applications using a CSS file.

Example CSS File (styles.css)

.button {
-fx-background-color: #4CAF50;
-fx-text-fill: white;
-fx-font-size: 14px;
-fx-padding: 10;
}

Applying CSS to FXML Components:


Add the stylesheet to the scene in your Java code:

scene.getStylesheets().add(getClass().getResource(“styles.css”).toEx-
ternalForm());
Or, reference the CSS file in the FXML file:
xml
Copy code
<VBox stylesheets=”@styles.css”>
<Button text=”Styled Button” />
</VBox>

Java FX App Window Structure:

In JavaFX, the application window is based on a hierarchical structure that


involves a Stage, a Scene, and Nodes. This structure defines how a JavaFX ap-
plication is built and rendered. Below is an overview of the JavaFX app window
structure.
1. The Stage:
The Stage is the top-level container or window of a JavaFX application. It represents the main win-
dow or dialog box where all the UI elements are displayed.

Key Points about Stage:


Primary Stage: Automatically created when the JavaFX application starts and passed to the
start(Stage primaryStage) method.
Additional stages can be created for dialog boxes or secondary windows.
A stage has properties like:
Title
Width and height
Modality (for dialog boxes)
Resizability
Code Example:

primaryStage.setTitle(“JavaFX Application”);
primaryStage.setWidth(400);
primaryStage.setHeight(300);
2. The Scene:
The Scene is the container for all UI elements in the Stage. It holds a scene graph, which is a hier-
archical tree structure of all nodes (controls, layouts, shapes, etc.).

Key Points about Scene:


Each Stage can have one Scene at a time.
A Scene defines the visual area of the application.
You can switch scenes in a stage dynamically.
Code Example:

Scene scene = new Scene(root, 400, 300); // root is the root node
primaryStage.setScene(scene);
3. The Node:
A Node is any visual element in the Scene. Examples include controls (Button, TextField), shapes
(Rectangle, Circle), and containers (VBox, HBox).

Key Points about Nodes:


All nodes are part of the scene graph.
Nodes are organized hierarchically:
Root Node: The top-level node in the scene graph.
Child Nodes: Nodes that are added to containers like VBox or HBox.
Hierarchy of a JavaFX App Window:

Stage (Window)
└── Scene (Content)
└── Root Node (Layout Container)
├── Child Node 1 (Control, Shape, etc.)
├── Child Node 2
└── Child Node N

JavaFX App Window Structure Example


Here is an example illustrating the JavaFX app window structure:

Code Example:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class AppWindowStructure extends Application {


@Override
public void start(Stage primaryStage) {
// Create nodes
Button button1 = new Button(“Button 1”);
Button button2 = new Button(“Button 2”);

// Root Node (Layout)


VBox root = new VBox(10); // VBox with 10px spacing
root.getChildren().addAll(button1, button2);

// Scene
Scene scene = new Scene(root, 300, 200);

// Configure Stage
primaryStage.setTitle(“JavaFX App Window Structure”);
primaryStage.setScene(scene);
primaryStage.show();
}

public static void main(String[] args) {


launch(args); // Launch the JavaFX application
}
}
displaying text image:
In JavaFX, you can display text and images in your application using the Text and
ImageView classes, respectively. Here’s how to do it step-by-step:

Displaying Text:
The Text class is used to render text in JavaFX. It provides options for customiz-
ing font, color, alignment, and more.

Example: Displaying Simple Text

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.scene.text.Text;
import javafx.stage.Stage;

public class DisplayText extends Application {


@Override
public void start(Stage primaryStage) {
// Create Text
Text text = new Text(“Hello, JavaFX!”);
text.setStyle(“-fx-font-size: 20; -fx-fill: blue;”);

// Create Layout
StackPane root = new StackPane(text);

// Create Scene
Scene scene = new Scene(root, 300, 200);

// Configure Stage
primaryStage.setTitle(“Display Text Example”);
primaryStage.setScene(scene);
primaryStage.show();
}

public static void main(String[] args) {


launch(args);
}
}
Displaying an Image:
The Image and ImageView classes are used to load and display images in JavaFX.

Steps to Display an Image:


Create an Image object using the file path or URL of the image.
Use an ImageView to display the image in the scene.
Example: Displaying an Image

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 DisplayImage extends Application {


@Override
public void start(Stage primaryStage) {
// Load Image
Image image = new Image(“file:example.png”); // Replace “example.png” with your image file path

// Create ImageView
ImageView imageView = new ImageView(image);

// Set ImageView Properties


imageView.setFitWidth(200); // Set the width of the image
imageView.setPreserveRatio(true); // Maintain aspect ratio

// Create Layout
StackPane root = new StackPane(imageView);

// Create Scene
Scene scene = new Scene(root, 300, 300);

// Configure Stage
primaryStage.setTitle(“Display Image Example”);
primaryStage.setScene(scene);
primaryStage.show();
}

public static void main(String[] args) {


launch(args);
}
}
Displaying Text and Image Together:
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.scene.text.Text;
import javafx.stage.Stage;

public class DisplayTextAndImage extends Application {


@Override
public void start(Stage primaryStage) {
// Create Text
Text text = new Text(“Welcome to JavaFX”);
text.setStyle(“-fx-font-size: 18; -fx-fill: darkgreen;”);

// Load Image
Image image = new Image(“file:example.png”); // Replace with your image file path
ImageView imageView = new ImageView(image);
imageView.setFitWidth(200);
imageView.setPreserveRatio(true);

// Combine Text and Image


VBox root = new VBox(10, text, imageView);

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

// Configure Stage
primaryStage.setTitle(“Text and Image Example”);
primaryStage.setScene(scene);
primaryStage.show();
}

public static void main(String[] args) {


launch(args);
}
}
Event Handling in JavaFX:

Event handling in JavaFX allows you to define actions that occur in response to user
interactions, such as button clicks, key presses, or mouse movements. JavaFX pro-
vides a robust event-handling mechanism using event listeners and handlers.
How Event Handling Works?
Event Source: The UI control that generates the event (e.g., a Button or TextField).
Event Object: Encapsulates information about the event (e.g., MouseEvent, Action-
Event).
Event Handler: A functional interface or lambda expression that defines the response
to the event.
Event Handling in Action:
1. Handling Button Click Events:

You can handle button click events using an EventHandler or a lambda expression.

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

public class ButtonEventExample extends Application {


@Override
public void start(Stage primaryStage) {
// Create a Button
Button button = new Button(“Click Me”);

// Set an Event Handler for the Button


button.setOnAction(event -> System.out.println(“Button Clicked!”));

// Add Button to Layout


StackPane root = new StackPane(button);
Scene scene = new Scene(root, 300, 200);

// Configure Stage
primaryStage.setTitle(“Button Event Example”);
primaryStage.setScene(scene);
primaryStage.show();
}

public static void main(String[] args) {


launch(args);
}
}
2. Handling Mouse Events:
JavaFX provides MouseEvent for handling mouse actions like clicks, movement,
and dragging.

Example:

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) {
// Create a Text Node
Text text = new Text(“Click anywhere!”);

// Set Mouse Event Handler


text.setOnMouseClicked(event -> {
text.setText(“Mouse clicked at: “ + event.getX() + “, “ + event.getY());
});

// Create Layout
StackPane root = new StackPane(text);
Scene scene = new Scene(root, 400, 300);

// Configure Stage
primaryStage.setTitle(“Mouse Event Example”);
primaryStage.setScene(scene);
primaryStage.show();
}

public static void main(String[] args) {


launch(args);
}
}
3. Handling Key Events
JavaFX provides KeyEvent for handling keyboard actions like key presses and releases.

Example:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.StackPane;
import javafx.scene.text.Text;
import javafx.stage.Stage;

public class KeyEventExample extends Application {


@Override
public void start(Stage primaryStage) {
// Create a Text Node
Text text = new Text(“Type something!”);

// Set Key Event Handler


text.setOnKeyPressed(event -> text.setText(“Key Pressed: “ + event.get-
Text()));

// Create Layout
StackPane root = new StackPane(text);
Scene scene = new Scene(root, 400, 300);

// Set Focus to Detect Key Events


root.setOnKeyPressed(event -> text.setText(“Key Pressed: “ + event.get-
Text()));
root.requestFocus();

// Configure Stage
primaryStage.setTitle(“Key Event Example”);
primaryStage.setScene(scene);
primaryStage.show();
}

public static void main(String[] args) {


launch(args);
}
laying out nodes in scene graph:
In JavaFX, the layout of nodes in the scene graph determines how the user inter-
face (UI) components are arranged within the application window. JavaFX pro-
vides several layout panes that handle the positioning and sizing of nodes auto-
matically based on their specific layout policies.
Positioning and Arranging Nodes:
1. Using a Pane
The Pane is the most basic layout container. You can position nodes manually by
setting their coordinates.
Example:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;

public class PaneExample extends Application {


@Override
public void start(Stage primaryStage) {
Pane pane = new Pane();

// Create Buttons and set their positions


Button button1 = new Button(“Button 1”);
button1.setLayoutX(50); // Set X-coordinate
button1.setLayoutY(50); // Set Y-coordinate

Button button2 = new Button(“Button 2”);


button2.setLayoutX(150);
button2.setLayoutY(100);

pane.getChildren().addAll(button1, button2);

Scene scene = new Scene(pane, 300, 200);


primaryStage.setTitle(“Pane Example”);
primaryStage.setScene(scene);
primaryStage.show();
}

public static void main(String[] args) {


launch(args);
}
}
2. Using HBox (Horizontal Layout):
The HBox arranges its child nodes in a single row.

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

public class HBoxExample extends Application {


@Override
public void start(Stage primaryStage) {
HBox hbox = new HBox(10); // 10px spacing between nodes

// Create Buttons
Button button1 = new Button(“Button 1”);
Button button2 = new Button(“Button 2”);
Button button3 = new Button(“Button 3”);

hbox.getChildren().addAll(button1, button2, button3);

Scene scene = new Scene(hbox, 300, 200);


primaryStage.setTitle(“HBox Example”);
primaryStage.setScene(scene);
primaryStage.show();
}

public static void main(String[] args) {


launch(args);
}
}
3. Using VBox (Vertical Layout):
The VBox arranges its child nodes in a single column.

Example:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class VBoxExample extends Application {


@Override
public void start(Stage primaryStage) {
VBox vbox = new VBox(10); // 10px spacing between nodes

// Create Buttons
Button button1 = new Button(“Button 1”);
Button button2 = new Button(“Button 2”);
Button button3 = new Button(“Button 3”);

vbox.getChildren().addAll(button1, button2, button3);

Scene scene = new Scene(vbox, 200, 300);


primaryStage.setTitle(“VBox Example”);
primaryStage.setScene(scene);
primaryStage.show();
}

public static void main(String[] args) {


launch(args);
}
}
4. Using GridPane
The GridPane arranges nodes in a grid of rows and columns.

Example:

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();

// Create Buttons and place them in specific rows and columns


Button button1 = new Button(“Button 1”);
Button button2 = new Button(“Button 2”);
Button button3 = new Button(“Button 3”);
Button button4 = new Button(“Button 4”);

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


gridPane.add(button2, 1, 0); // (column 1, row 0)
gridPane.add(button3, 0, 1); // (column 0, row 1)
gridPane.add(button4, 1, 1); // (column 1, row 1)

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


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

public static void main(String[] args) {


launch(args);
}
}
5. Using BorderPane:
The BorderPane divides the layout into five regions: top, bottom, left, right, and cen-
ter.

Example:

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) {
BorderPane borderPane = new BorderPane();

// Add Buttons to different regions


Button top = new Button(“Top”);
Button bottom = new Button(“Bottom”);
Button left = new Button(“Left”);
Button right = new Button(“Right”);
Button center = new Button(“Center”);

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

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


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

public static void main(String[] args) {


launch(args);
}
}
Combining Layouts:
You can nest multiple layout panes to create complex UI designs. For
example, using an HBox inside a VBox:

Example:

HBox hbox = new HBox(10, new Button(“Button 1”), new Button(“Button


2”));
VBox vbox = new VBox(20, new Button(“Top”), hbox, new Button(“Bot-
tom”));

Scene scene = new Scene(vbox, 300, 200);

Mouse Events in JavaFX:


JavaFX provides powerful support for handling mouse events, allowing developers
to respond to various mouse actions like clicks, movements, drags, and scrolls.
Mouse events are represented by the MouseEvent class, and you can register
handlers to nodes using methods such as setOnMouseClicked, setOnMouse-
Moved, etc.
Basic Example: Handling Mouse Clicks:
This example demonstrates how to handle a mouse click event on a Rectangle.

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class MouseClickExample extends Application {


@Override
public void start(Stage primaryStage) {
// Create a Rectangle
Rectangle rectangle = new Rectangle(100, 100, 200, 150);
rectangle.setFill(Color.LIGHTBLUE);

// Set Mouse Click Event Handler


rectangle.setOnMouseClicked(event -> {
System.out.println(“Rectangle clicked at: “ + event.getX() + “, “ + event.
getY());
rectangle.setFill(Color.LIGHTGREEN); // Change color on click
});

// Add to Layout
Pane root = new Pane(rectangle);
Scene scene = new Scene(root, 400, 300);

// Configure Stage
primaryStage.setTitle(“Mouse Click Example”);
primaryStage.setScene(scene);
primaryStage.show();
}

public static void main(String[] args) {


launch(args);
}
}
Example: Mouse Pressed, Released, and Dragged
This example demonstrates handling multiple mouse events like MOUSE_PRESSED, MOUSE_RE-
LEASED, and MOUSE_DRAGGED.

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;

public class MouseDragExample extends Application {


@Override
public void start(Stage primaryStage) {
// Create a Circle
Circle circle = new Circle(200, 150, 50, Color.ORANGE);

// Set Mouse Press Event


circle.setOnMousePressed(event -> circle.setFill(Color.RED));

// Set Mouse Released Event


circle.setOnMouseReleased(event -> circle.setFill(Color.ORANGE));

// Set Mouse Dragged Event


circle.setOnMouseDragged(event -> {
circle.setCenterX(event.getX());
circle.setCenterY(event.getY());
});

// Add to Layout
Pane root = new Pane(circle);
Scene scene = new Scene(root, 400, 300);

// Configure Stage
primaryStage.setTitle(“Mouse Drag Example”);
primaryStage.setScene(scene);
primaryStage.show();
}

public static void main(String[] args) {


launch(args);
}
}
Example: Mouse Movement and Enter/Exit Events:
You can track mouse movement and detect when it enters or exits a node.

java
Copy code
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class MouseMovementExample extends Application {


@Override
public void start(Stage primaryStage) {
// Create a Rectangle
Rectangle rectangle = new Rectangle(100, 100, 200, 150);
rectangle.setFill(Color.LIGHTGRAY);

// Set Mouse Enter Event


rectangle.setOnMouseEntered(event -> rectangle.setFill(Color.LIGHTBLUE));

// Set Mouse Exit Event


rectangle.setOnMouseExited(event -> rectangle.setFill(Color.LIGHTGRAY));

// Set Mouse Moved Event


rectangle.setOnMouseMoved(event -> {
System.out.println(“Mouse moved at: “ + event.getX() + “, “ + event.getY());
});

// Add to Layout
Pane root = new Pane(rectangle);
Scene scene = new Scene(root, 400, 300);

// Configure Stage
primaryStage.setTitle(“Mouse Movement Example”);
primaryStage.setScene(scene);
primaryStage.show();
}

public static void main(String[] args) {


launch(args);
}
}
Example: Scroll Events:
You can handle mouse scroll events using the SCROLL event type.

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;

public class MouseScrollExample extends Application {


@Override
public void start(Stage primaryStage) {
// Create a Circle
Circle circle = new Circle(200, 150, 50, Color.PURPLE);

// Set Scroll Event Handler


circle.setOnScroll(event -> {
double deltaY = event.getDeltaY();
double newRadius = circle.getRadius() + deltaY / 10; // Scale radius
circle.setRadius(Math.max(10, newRadius)); // Minimum radius of 10
});

// Add to Layout
Pane root = new Pane(circle);
Scene scene = new Scene(root, 400, 300);

// Configure Stage
primaryStage.setTitle(“Mouse Scroll Example”);
primaryStage.setScene(scene);
primaryStage.show();
}

public static void main(String[] args) {


launch(args);
}
}

You might also like