Oops Through Java by Vikram Dunga
Oops Through Java by Vikram Dunga
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 - 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 – 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)
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.
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
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.
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.
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:
// 3. Class Declaration
public class Main {
// 4. Main Method
public static void main(String[] args) {
a) Local Variables
Declared inside a method, constructor, or block.
Only accessible within the block where they are defined.
Must be initialized before use.
Variable Scope:
The scope of a variable defines where it can be accessed:
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:
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:
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
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:
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:
if (condition) {
// Code if condition is true
} else {
// Code if condition is false
}
Example:
if (condition1) {
// Code if condition1 is true
} else if (condition2) {
// Code if condition2 is true
} else {
// Code if all conditions are false
}
Example:
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.
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:
// 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.
// 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:
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
a. Parameterized Methods:
Methods that accept input parameters.
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:
Static Methods:
class MathUtility {
public static int square(int x) {
return x * x;
}
}
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);
}
}
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);
}
}
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);
}
}
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);
}
}
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);
}
}
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;
}
class Config {
static String appName;
// Static block
static {
appName = “MyApplication”;
System.out.println(“Static block executed”);
}
}
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;
void display() {
System.out.println(“Name: “ + name);
}
}
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);
}
}
// Syntax
dataType[] arrayName; // Preferred
dataType arrayName[]; // Valid but less common
Examples:
b. Creating an Array:
Arrays are created using the new keyword, specifying the type and size.
// 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
a. Single-Dimensional Arrays:
A single row or list of elements.
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:
c. Sorting an Array
import java.util.Arrays;
3. Example Program
Example 1: Printing Command-Line Arguments
Command-line arguments:
args[0]: Hello
args[1]: World
args[2]: Java
4. Use Cases of Command-Line Arguments:
class OuterClass {
static class StaticNestedClass {
void display() {
System.out.println(“Inside Static Nested Class”);
}
}
}
Example
void instanceMethod() {
System.out.println(“Instance method in static nested class”);
}
}
class OuterClass {
class InnerClass {
void display() {
System.out.println(“Inside Non-Static Inner Class”);
}
}
}
Example
class Inner {
void display() {
System.out.println(message);
}
}
class OuterClass {
void someMethod() {
class LocalInnerClass {
void display() {
System.out.println(“Inside Local Inner Class”);
}
}
LocalInnerClass inner = new LocalInnerClass();
inner.display();
}
}
Example
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:
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;
1. Creating Strings
Strings can be created in two ways:
4. String Concatenation:
a. Using + Operator
String s1 = “Hello”;
String s2 = “World”;
String result = s1 + “ “ + s2;
System.out.println(result); // Output: Hello World
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:
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
Inheritance Syntax:
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”);
}
}
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”);
}
}
interface A {
void methodA();
}
interface B {
void methodB();
}
class C implements A, B {
public void methodA() {
System.out.println(“Method from Interface A”);
}
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 B {
void display() {
System.out.println(“Class B”);
}
}
class Parent {
String name = “Parent”;
}
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!
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.
class Example {
public static void main(String[] args) {
final int MAX_VALUE = 100;
System.out.println(“Max Value: “ + MAX_VALUE);
class Parent {
final void display() {
System.out.println(“This is a final method.”);
}
}
keyword usage
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:
class Calculator {
int multiply(int a, int b) {
return a * b;
}
Multiplication of integers: 50
Multiplication of doubles: 10.0
Rules for Method Overloading
Return Type Does Not Differentiate Methods:
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.
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.
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:
class Parent {
void display() {
System.out.println(“Display method in Parent class”);
}
}
These are methods declared without a body. Subclasses must provide their implementation.
Syntax:
Non-Abstract 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.
// Constructor
Vehicle(String brand) {
this.brand = brand;
}
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();
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
Encapsulation:
Interfaces help separate implementation details from functionality.
Flexibility:
Different classes can implement the same interface in different ways.
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.
// File: mypackage/MyClass.java
package mypackage;
// File: Main.java
import mypackage.MyClass; // Import the package
1. Command-Line Setting
Temporary Classpath Setting: Use the -classpath or -cp option with javac or java.
2. Environment Variable
Set the CLASSPATH environment variable.
Windows:
set CLASSPATH=path1;path2;...
// File: MyClass.java
package mypackage;
javac -d . MyClass.java
Run using classpath:
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:
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.
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.
The throws keyword is used in method declarations to indicate that a method might throw excep-
tions.
try {
int result = 10 / 0;
String str = null;
System.out.println(str.length());
} catch (ArithmeticException | NullPointerException e) {
System.out.println(“Exception occurred: “ + e);
}
Example:
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:
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.
// 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
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:
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.
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().
ex:
class MyThread extends Thread {
public void run() {
System.out.println(“Thread is running”);
}
}
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
// Setting priorities
t1.setPriority(Thread.MIN_PRIORITY); // Priority 1
t2.setPriority(Thread.NORM_PRIORITY); // Priority 5
t3.setPriority(Thread.MAX_PRIORITY); // Priority 10
// 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.
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.
import java.io.File;
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;
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):
The framework is part of the java.util package and is widely used for handling dynamic and com-
plex data structures.
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.
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;
// 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”);
// Check size
System.out.println(“Size of list: “ + fruits.size());
}
}
import java.util.ArrayList;
// Add elements
numbers.add(10);
numbers.add(20);
numbers.add(30);
import java.util.ArrayList;
import java.util.Collections;
import java.util.ArrayList;
// 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;
// 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”);
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;
import java.util.LinkedList;
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.
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.
// Add elements
set.add(“Apple”);
set.add(“Banana”);
set.add(“Cherry”);
set.add(“Apple”); // Duplicate element, ignored
// Remove an element
set.remove(“Cherry”);
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).
No Duplicates:
Like all Set implementations, it does not allow duplicate elements.
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;
// Adding elements
set.add(“Apple”);
set.add(“Banana”);
set.add(“Cherry”);
set.add(“Apple”); // Duplicate, won’t be added
// Remove an element
set.remove(“Banana”);
System.out.println(“After removing ‘Banana’: “ + set);
o/p :
Apple
Banana
Cherry
Contains ‘Banana’: true
After removing ‘Banana’: [Apple, Cherry]
Size of the set: 2
Methods in LinkedHashSet:
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.
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;
// Adding elements
numbers.add(10);
numbers.add(20);
numbers.add(5);
numbers.add(15);
// 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:
import java.util.TreeSet;
EXAMPLE:
import java.util.LinkedList;
import java.util.Queue;
Using PriorityQueue:
A PriorityQueue orders elements based on their natural order or a custom comparator.
import java.util.PriorityQueue;
// Add elements
pq.add(20);
pq.add(10);
pq.add(30);
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;
// Add elements
queue.offer(“Alice”);
queue.offer(“Bob”);
queue.offer(“Charlie”);
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.
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:
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:
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.
System.out.println(map);
Output:
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:
import java.util.TreeMap;
public class Main {
public static void main(String[] args) {
// Create a TreeMap
TreeMap<String, Integer> map = new TreeMap<>();
// Retrieve a value
System.out.println(“Value for ‘Banana’: “ + map.get(“Banana”));
// Remove a key
map.remove(“Cherry”);
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;
// 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);
LinkedHashMap Declaration:
To declare a LinkedHashMap:
// 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.
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;
// 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;
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.
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
// Create a scene
Scene scene = new Scene(root, 300, 200);
Application Class:
The entry point for JavaFX applications. It contains the start method
where the UI is initialized.
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);
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.VBox?>
Java file:
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
primaryStage.setTitle(“FXML Example”);
primaryStage.setScene(scene);
primaryStage.show();
}
// Apply CSS
scene.getStylesheets().add(getClass().getResource(“styles.css”).toExternal-
Form());
primaryStage.setTitle(“CSS Example”);
primaryStage.setScene(scene);
primaryStage.show();
}
After downloading the appropriate version for your operating system, follow the
installation instructions provided.
Integration with IDEs:
Example:
FXML File (layout.fxml)
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
.button {
-fx-background-color: #4CAF50;
-fx-text-fill: white;
-fx-font-size: 14px;
-fx-padding: 10;
}
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>
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.).
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).
Stage (Window)
└── Scene (Content)
└── Root Node (Layout Container)
├── Child Node 1 (Control, Shape, etc.)
├── Child Node 2
└── Child Node N
Code Example:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
// Scene
Scene scene = new Scene(root, 300, 200);
// Configure Stage
primaryStage.setTitle(“JavaFX App Window Structure”);
primaryStage.setScene(scene);
primaryStage.show();
}
Displaying Text:
The Text class is used to render text in JavaFX. It provides options for customiz-
ing font, color, alignment, and more.
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.scene.text.Text;
import javafx.stage.Stage;
// 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();
}
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;
// Create ImageView
ImageView imageView = new ImageView(image);
// 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();
}
// 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);
// Create Scene
Scene scene = new Scene(root, 300, 400);
// Configure Stage
primaryStage.setTitle(“Text and Image Example”);
primaryStage.setScene(scene);
primaryStage.show();
}
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;
// Configure Stage
primaryStage.setTitle(“Button Event Example”);
primaryStage.setScene(scene);
primaryStage.show();
}
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;
// 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();
}
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;
// Create Layout
StackPane root = new StackPane(text);
Scene scene = new Scene(root, 400, 300);
// Configure Stage
primaryStage.setTitle(“Key Event Example”);
primaryStage.setScene(scene);
primaryStage.show();
}
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
pane.getChildren().addAll(button1, button2);
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;
// Create Buttons
Button button1 = new Button(“Button 1”);
Button button2 = new Button(“Button 2”);
Button button3 = new Button(“Button 3”);
Example:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
// Create Buttons
Button button1 = new Button(“Button 1”);
Button button2 = new Button(“Button 2”);
Button button3 = new Button(“Button 3”);
Example:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
Example:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
borderPane.setTop(top);
borderPane.setBottom(bottom);
borderPane.setLeft(left);
borderPane.setRight(right);
borderPane.setCenter(center);
Example:
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;
// 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();
}
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;
// 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();
}
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;
// 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();
}
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;
// 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();
}