Java E-book Vcodez
Java E-book Vcodez
Java Versions
Java Editions
Features of Java
Datatypes in java
Typecasting
Introduction of Collection
Database
MySQL Database
Constraints in SQL
SQL Operators
Arithmetic Operators
Comparison Operators
Logical Operators
LIKE Operator
View in SQL
Creating a View
Using a View
Trigger in SQL
Constraint in SQL
Foreign Key
Join in SQL
INNER JOIN
LEFT JOIN
Index in SQL
Creating an Index
Data Integrity
Subquery in SQL
JAVASCRIPT
Introduction to JavaScript
Key Features of JavaScript
Advantages of Using JavaScript
Variables in JavaScript
Operators in JavaScript
Data Types in JavaScript
Conditional Statement in JavaScript
Loops in JavaScript
Template Literals in JavaScript
Objects and Arrays in JavaScript
Functions in JavaScript
Events in JavaScript
DOM Manipulation in JavaScript
Promises And Async/Await in JavaScript
TYPESCRIPT
Introduction to TypeScript
Data Types in TypeScript
Functions in TypeScript
Objects in TypeScript
Defining Objects
Aliases
Union Types
Intersection Types
Type Guards
The Never Type
Type Assertions
Modern JavaScript Features
ANGULAR
Introduction to Angular
Overview of Angular
Importance of TypeScript
History of Angular
Initial Announcement
Key Development Stages
Ivy Compilation and Angular 13 Updates
Naming Clarification
AngularJS vs Angular
Key Features of Angular
Differences Between Angular and AngularJS
Starting a New Angular Project
Prerequisites
Installing Angular CLI
Project Setup and Running
Angular Project Structure
Root Folder Overview
Configuration Files
Dependencies and Build Output
Components in Angular
Creating Components with Angular CLI
Common CLI Options for Components
Angular Lifecycle Hooks
Angular Services
Injecting Services
@Injectable Decorator
Injection Scope (Root, Module, Component Level)
Modules in Angular
@NgModule Decorator
Declarations, Imports, Exports, Providers, Bootstrap
Angular Directives
Attribute Directives
Structural Directives
Custom Directives
Pipes
Overview of Pipes
Built-in Pipes
Using Multiple Pipes
Forms in Angular
Template-driven Forms
Reactive Forms
Form Validation
FormControl and FormGroup
Custom Validators
Decorators in Angular
Overview of Decorators
Types of Decorators
Class Decorators
Property Decorators
Method Decorators
Parameter Decorators
Accessor Decorators
Custom Decorators
Routing in Angular
Overview of Angular Router
Setting up Routes
Route Guards (e.g., CanActivate, CanDeactivate)
Lazy Loading Modules
Nested Routes and Child Routes
HTTP and Observables
HttpClient Module
Making HTTP Requests
Observables and RxJS
Handling HTTP Responses and Errors
HTTP Interceptors
Heading
Introduction
Java EE Layers
Servlet Request-Response Cycle
JDBC Flow
JSP in MVC Architecture
Java EE Application Workflow
JDBC (Java Database Connectivity)
Components of JDBC
Types of JDBC Drivers
Establishing a Database Connection
JDBC API Methods with Examples
Best Practices for JDBC Programming
Spring Framework
Spring Boot
Injection Types
INTRODUCTION TO JAVA
Microsystems, led by James Gosling and his team, and officially released to the public on
May 23, 1995. Java was created as part of a project initially called "Green" and was later
named after Java coffee, reflecting its goal of being energizing and ubiquitous. Designed with the
principle of "Write Once, Run Anywhere" (WORA), Java introduced a revolutionary
approach to software development by enabling applications to run seamlessly across different
platforms through the Java Virtual Machine (JVM).
Initially aimed at interactive TV systems, Java soon evolved to dominate areas such as web
development, mobile applications (especially Android), enterprise solutions, gaming, and even
Internet of Things (IoT) devices. Over the years, Java has maintained its relevance with regular
updates and a thriving developer community, becoming one of the most widely used
programming languages globally. Its release marked a significant milestone in computing
history, and today it remains a vital tool for developers across industries.
JAVA VERSIONS
Overview
Java Standard Edition (Java SE) is the foundation of the Java platform, offering the core tools
and libraries needed for developing general-purpose applications. It includes the Java
programming language, essential APIs, and the Java Virtual Machine (JVM), which ensures
cross-platform execution. Java SE is the building block for all other editions and serves as the
entry point for most developers.
Key Features
Core APIs: Provides libraries for fundamental programming needs like collections,
networking, I/O, multithreading, and exception handling.
Java Virtual Machine (JVM): The runtime engine that enables Java applications to
run on any operating system.
Tools for Development: Comes with the Java Development Kit (JDK), which
includes:
o A compiler for converting source code into bytecode.
o Debugging tools for identifying and resolving issues.
o The Java Runtime Environment (JRE) for running compiled programs.
Security: Offers built-in mechanisms like cryptography and secure coding practices.
Applications
Desktop software.
Command-line utilities.
Applications requiring portability across platforms.
Examples
Overview
Java Enterprise Edition (Java EE), now rebranded as Jakarta EE, extends Java SE by
providing a robust framework for developing distributed, scalable, and secure enterprise-level
applications. Designed for large organizations, it supports the creation of web, server-side, and
cloud-based applications that handle complex workflows and high traffic.
Key Features
Web Development: Includes technologies like Servlets and JSP (JavaServer Pages)
for dynamic content generation.
Enterprise APIs: Offers frameworks like JPA (Java Persistence API) for database
interaction, JMS (Java Messaging Service) for messaging, and EJB (Enterprise
JavaBeans) for implementing business logic.
Scalability: Built-in support for clustering, load balancing, and session management.
Security: Enterprise-grade features like role-based access control and encryption.
Integration: Facilitates integration with external systems via web services and REST
APIs.
Applications
Examples
Overview
Java Micro Edition (Java ME) is a lightweight and specialized version of Java designed for
devices with limited resources, such as embedded systems, feature phones, and Internet of
Things (IoT) devices. It provides a compact runtime environment and a subset of Java SE
functionalities, optimized for low-memory and low-power environments.
Key Features
Applications
Mobile apps for feature phones.
Embedded software in appliances and vehicles.
IoT solutions like smart home systems and wearable devices.
Examples
4. JavaFX
Overview
JavaFX is a framework focused on building modern, visually rich applications with sophisticated
user interfaces. It was introduced as a replacement for older GUI frameworks like Swing and
AWT. JavaFX simplifies the development of desktop applications with features like CSS styling,
multimedia support, and advanced animation capabilities.
Key Features
Rich UI Components: Offers pre-built controls like buttons, charts, and tables.
Multimedia Integration: Supports video and audio playback, enabling multimedia-
rich applications.
2D/3D Graphics: Provides APIs for rendering complex graphics and animations.
FXML: Allows developers to define UI elements using an XML-based scripting
language.
Web Content Integration: Embeds web pages and dynamic content through
WebView.
Applications
Desktop applications with interactive user interfaces.
Visualization tools for data analysis and reporting.
Media-centric tools like video players and graphic design software.
Examples
Java Lightweight Java for Embedded systems, IoT, and Smart devices, early
ME constrained devices feature phones mobile games
Rich client applications with Interactive desktop tools and Data dashboards,
JavaFX
advanced UIs media software graphic tools
Java's editions are designed to meet the diverse needs of developers, making it a powerful
platform for building applications across a wide range of devices and industries.
JDK,JRE,JVM
The Java Development Kit (JDK) is a complete software development package provided
by Oracle for building Java applications. It contains a set of development tools, libraries, and
frameworks required to create, compile, and run Java programs. The key component of the JDK
is the Java Compiler (javac), which converts human-readable source code into bytecode, a
machine-independent code that the Java Virtual Machine (JVM) can execute. The JDK also
includes the Java Runtime Environment (JRE), which provides the necessary runtime
libraries and the JVM itself for executing Java programs. Additionally, the JDK includes
debugging tools (like jdb), utilities for packaging Java applications into JAR (Java
Archive) files, and documentation to assist developers in writing code efficiently. Developers
rely on the JDK to create everything from simple console applications to large-scale enterprise
software, and it is essential for anyone who writes or compiles Java code.
The Java Virtual Machine (JVM) is an abstract computing machine that enables a
computer to run Java programs. It is an essential component of the Java platform that provides
the environment in which Java bytecode can be executed, regardless of the underlying hardware
and operating system. The JVM performs crucial tasks such as interpreting or compiling
bytecode into native machine code, managing memory (using a garbage collector to
automatically reclaim memory), and providing platform independence. This means that Java
programs can run on any device or operating system with a compatible JVM installed, following
the "write once, run anywhere" philosophy. The JVM has three main parts: the class loader,
which loads the class files; the execution engine, which runs the bytecode; and the garbage
The Java Runtime Environment (JRE) is the environment in which Java applications are
executed. It includes the JVM, which is responsible for running Java bytecode, and the
necessary libraries and files to support the application at runtime. The JRE provides essential
components such as class libraries, which consist of Java API packages that offer functionality
like I/O operations, networking, database access, and more. However, the JRE does not include
development tools like the Java compiler (javac), which are essential for building Java
applications, making it distinct from the JDK. The primary function of the JRE is to provide a
runtime environment for users to run Java applications without needing to install the full
development environment. It is typically used by individuals who only want to run Java
programs, such as end-users or systems administrators. Without the JRE, a user cannot run a Java
application because it lacks the necessary components to execute the bytecode produced by the
JDK.
FEATURES OF JAVA
1. Simple
Java was designed with simplicity in mind. One of its main objectives was to create a
language that was easy to learn, use, and maintain. It simplifies many features that other
programming languages (like C and C++) struggle with, such as pointer arithmetic,
manual memory management, and complex syntax. Java does not allow direct access
to memory, which significantly reduces the risk of errors like memory corruption. Additionally,
Java’s clear syntax, which is influenced by C, makes it easier for developers to pick up and build
applications without facing steep learning curves.
2. Object-Oriented
3. Portable
Java is portable because it follows the principle of "Write Once, Run Anywhere."
Unlike other programming languages, Java doesn’t compile directly into machine code specific
to a hardware architecture. Instead, it compiles into bytecode, which can be run on any
machine that has a Java Virtual Machine (JVM) installed. This allows Java programs to
execute seamlessly across different operating systems like Windows, macOS, and Linux without
needing any modifications. The ability to execute the same code across various environments
without recompilation is one of Java's strongest features for enterprise applications.
4. Platform Independent
One of Java's standout qualities is its platform independence. When Java code is
compiled, it is converted into an intermediate form known as bytecode. This bytecode is not
dependent on any specific operating system or hardware architecture. When you run the Java
application, the JVM interprets the bytecode and converts it into machine-specific instructions
based on the platform it is running on. This ability to execute on any platform with a JVM allows
Java to be used in diverse environments, from mobile devices to enterprise servers, making it a
highly adaptable language for modern applications.
5. Secured
6. Robust
ensure reliable execution. One of these features is automatic garbage collection, which
prevents memory leaks by automatically reclaiming memory that is no longer in use.
Additionally, Java’s strong type checking and exception handling mechanism ensure that
programs are less prone to errors. The language also enforces strict null-pointer checks and
bounds checking to avoid crashes or unexpected behavior. These features make Java
applications more stable and less likely to fail during execution.
7. Architecture Neutral
Java is architecture neutral because the bytecode generated by the Java compiler is
not tied to any specific processor architecture. Unlike languages that generate machine-specific
code, Java bytecode is designed to be executed on any machine with a compatible JVM. Whether
the host system is based on an Intel processor or an ARM processor, Java bytecode
remains consistent. This architecture-neutral approach means developers don’t have to worry
about hardware-specific optimizations, and Java programs can seamlessly run across various
platforms, from desktops to cloud-based servers.
8. Interpreted
Java is an interpreted language, which means its bytecode is not directly executed by
the operating system's native processor. Instead, the Java Virtual Machine (JVM)
interprets the bytecode and converts it into machine-specific instructions during runtime. This
layer of interpretation allows for portability since the JVM can be implemented on any
platform. Java also employs Just-In-Time (JIT) compilation, where frequently executed
bytecode is compiled into native machine code at runtime for better performance. JIT
compilation allows Java to strike a balance between the flexibility of interpretation and the
performance of native code execution.
9. High Performance
optimizations. The Just-In-Time (JIT) compiler converts frequently executed bytecode into
10. Multithreaded
11. Distributed
Java has extensive support for distributed computing, allowing developers to create
applications that run on multiple machines across a network. Java provides powerful tools for
building distributed systems, such as Remote Method Invocation (RMI), which allows
objects to communicate with each other over a network as if they were local. Other features, like
Java Message Service (JMS) and Sockets, help with message-based communication,
enabling seamless data exchange between distributed applications. Java’s built-in networking
capabilities make it a great choice for developing web applications, cloud-based systems, and
enterprise solutions that require distributed processing and communication.
12. Dynamic
runtime. For instance, Java allows for dynamic class loading, where classes are loaded into
memory only when needed, which makes the application more flexible. Java’s reflection API
enables runtime inspection and modification of classes, methods, and fields, allowing developers
to build more dynamic and extensible applications. This dynamic capability is also essential in
scenarios where Java applications need to interact with external libraries or plugins that can be
added or updated without restarting the application.
KEYWORDS IN JAVA
In Java, keywords are reserved words that have a predefined meaning and serve a specific
function in the language. They are fundamental to Java's syntax and structure and cannot be used
as identifiers (such as names for variables, methods, or classes). Keywords help define the
behavior, flow, and structure of a Java program. They form the core building blocks that allow
the programmer to define logic, control the program flow, and interact with objects. Java has a
set of 50 keywords that the Java compiler recognizes and interprets in a specific way. These
keywords cover various aspects of Java, including class declarations, control flow, error
handling, access control, and object-oriented concepts.
class: Defines a class, which is a template for creating objects and defining methods and
attributes.
public: Specifies that a member (method, variable) is accessible from any other class.
private: Specifies that a member (method, variable) is accessible only within its own
class.
protected: Specifies that a member is accessible within its own package and by
subclasses.
static: Defines a member (method or variable) that belongs to the class rather than
instances of the class.
final: Used to declare constants, prevent method overriding, or prevent inheritance of a
class.
void: Specifies that a method does not return any value.
if: Defines a conditional statement to execute code based on a boolean expression.
else: Specifies the alternative block of code in an if-else statement.
for: Defines a loop that executes a block of code a specified number of times.
return: Used to return a value from a method or to exit from a method.
try: Defines a block of code that may throw an exception, used in conjunction with catch
and finally.
catch: Used to handle exceptions that occur in a try block.
import: Imports other classes or packages into the current class to use them.
new: Used to create new objects or arrays in Java.
IDENTIFIERS IN JAVA
In Java, identifiers are names used to refer to various program elements such as
variables, methods, classes, and objects. They play a crucial role in allowing developers to
reference and manipulate data throughout the program. Java has specific rules for naming
identifiers: they must begin with a letter (a-z, A-Z), an underscore (_), or a dollar sign ($),
followed by any combination of letters, digits (0-9), underscores, or dollar signs. Importantly,
Java is case-sensitive, so identifiers like myVariable and MyVariable would be treated as
distinct. Identifiers cannot be the same as reserved keywords in Java, such as if, for, or class.
While identifiers can be of any length, it’s best practice to use meaningful names that describe
the purpose of the variable or method to make the code more readable. Common naming
conventions include using camel case (e.g., totalAmount) for variables and methods, and Pascal
case (e.g., StudentDetails) for class names. Avoid using digits at the beginning of identifiers, and
refrain from using special characters other than underscores and dollar signs.
Examples:-
Valid Identifiers:
totalAmount
customerName
calculateSalary
EmployeeDetails
_value
$amount
itemCount
Invalid Identifiers:
PACKAGES IN JAVA
In Java, a package is a namespace that organizes a set of related classes, interfaces, and
sub-packages. It serves as a way to group classes logically, preventing naming conflicts and
enhancing the organization of code. Packages are essential in managing large-scale Java
applications, ensuring that the code is modular, easily maintainable, and accessible by other
programs.
Uses of Packages:
1. Name Collision Prevention: By grouping classes into different packages, you can
avoid conflicts between classes with the same name but different functionalities. For
example, two packages can both have a Date class, but they will not conflict if they are in
different namespaces (like java.util.Date and java.sql.Date).
2. Access Control: Packages play a key role in access control. Java uses access modifiers
like public, protected, and private to control the visibility of classes and their members.
Classes in the same package can access each other’s members with default (package-
private) access or protected access.
3. Code Organization: Packages help in organizing code by logically grouping classes
that share common functionality, making it easier to maintain and navigate. This is
particularly useful in large projects.
4. Reusability: When classes are packaged together, they can be reused in different parts
of the same project or in other projects, enhancing modularity and reducing redundancy.
Types of Packages:
In Java, a data type is a fundamental aspect of the language, defining the type and
range of values a variable can hold and the operations that can be performed on it. Data types
help allocate the appropriate amount of memory for storing data and ensure that operations on
variables are valid and predictable. This strict classification contributes to Java’s reputation as a
statically-typed and type-safe language, where the type of a variable must be declared at the time
of its creation. For instance, specifying int for an integer value ensures that only whole numbers
can be stored, while a boolean is restricted to true or false.
Data types are crucial in enforcing program stability and preventing errors such as
assigning invalid data to a variable. They allow the compiler to detect type mismatches during
compile time rather than at runtime, significantly reducing potential bugs. Java offers a diverse
range of data types, categorized into primitive and non-primitive types, allowing
developers to store simple data (like numbers and characters) as well as complex data (like
arrays, objects, and strings).
In Java, primitive data types are the most fundamental building blocks of data storage and
computation. They are predefined by the language and represent simple values such as integers,
floating-point numbers, characters, and boolean logic. Unlike objects, primitive data types store
actual values directly in memory and are not associated with methods or additional properties,
making them efficient and lightweight. These types are used for core functionalities, such as
performing mathematical operations, storing state variables, and handling logical decisions in
programs. While Java is predominantly object-oriented, its use of primitive data types is one
reason it is not considered a 100% object-oriented language. Primitive types are not objects; they
cannot inherit from classes or participate in the object hierarchy. This deliberate design choice
ensures better performance and simpler handling of basic data, balancing object-oriented
principles with practicality and efficiency.
BYTE:
In Java, byte is one of the eight primitive data types. It is used to represent small integer values.
A byte occupies 1 byte (8 bits) of memory and can store values in the range of -128 to 127.
This makes it particularly useful for situations where memory efficiency is crucial and the range
of values is limited to these small integers.
EXAMPLE PROGRAM :-
public class ByteProgram {
}}
OUTPUT:
SHORT
In Java, short is one of the primitive data types used to store small integer values. It is larger
than a byte but smaller than an int, making it suitable for situations where memory usage is a
concern, but a byte is too small to handle the required range of values.
EXAMPLE PROGRAM:-
}}
OUTPUT:-
INT
In Java, int is a primitive data type used to store whole numbers (integers). It is one of the most
commonly used data types because it provides a balance between memory efficiency and a wide
range of values. The int data type is ideal for general-purpose numerical operations where the
range of values is expected to fit within its limits.
EXAMPLE PROGRAM:-
int num2 = 7;
OUTPUT:-
Sum: 22
Difference: 8
Product: 105
Quotient: 2
LONG
In Java, long is a primitive data type used to store large integer values. It is an extended version
of int with a much larger range, making it suitable for applications that require handling very
large numerical values beyond the capacity of int.
EXAMPLE PROGRAM:-
OUTPUT:-
FLOAT
In Java, the float data type is a single-precision, 32-bit IEEE 754 floating-point number used to
store decimal values. It is designed for scenarios where memory efficiency is more important
than precision. Unlike integer types, float can handle fractional values, making it suitable for
measurements, approximations, and calculations where exact precision is not critical.
EXAMPLE PROGRAM:-
}}
OUTPUT:-
DOUBLE
In Java, double is a primitive data type used to represent floating-point numbers with double
precision. It is part of the IEEE 754 standard for floating-point arithmetic, which specifies how
floating-point numbers are stored and manipulated. The double data type is used to store decimal
values where higher precision is required, and it allows for more accurate representation of
numbers than its counterpart, the float.
EXAMPLE PROGRAM:-
double pi = 3.141592653589793;
OUTPUT:-
CHAR
In Java, char is a primitive data type that is used to store a single character. Internally, it is
represented as a 16-bit unsigned integer. This means that each char value occupies 2 bytes
(16 bits) in memory. The reason for this is that Java uses the Unicode character set, which
can represent a wide range of characters, symbols, and even characters from different languages,
extending beyond the basic ASCII character set.
EXAMPLE PROGRAM:-
OUTPUT:-
Character: A
Unicode Value (Internal Storage): 65
BOOLEAN
In Java, the boolean data type is one of the eight primitive data types and is primarily used to
store binary values. A boolean can only have two possible values: true or false. These two
values represent the fundamental concept of logical truth, which is essential in decision-making
and flow control within a program.
EXAMPLE PROGRAM:-
System.out.println("Access granted.");
} else {
System.out.println("Access denied.");
}}
OUTPUT:-
Access granted.
Eligible for discount: true
STRINGS IN JAVA
In Java, a String is a sequence of characters used to represent textual data. Strings are objects of
the String class in the java.lang package and are among the most commonly used data types in
Java programming. Strings in Java are immutable, meaning once created, their content cannot
be changed. This immutability provides security, makes them thread-safe, and optimizes memory
usage by leveraging a feature called the string pool. Strings can be declared and used in
various ways, with each approach affecting how they are stored in memory. The two primary
types of strings in Java are String Literal and String Object.
Strings in Java can be created and managed using two primary approaches they are:
1. String Literal
2. String Object
1.STRING LITERALS
A string literal is created when you assign a value directly to a String variable using double
quotes, This approach stores the string in a special memory area called the string constant
pool, which resides in the heap memory. The constant pool optimizes memory usage by
avoiding duplicate strings. If a string with the same value already exists in the pool, the reference
to that string is reused instead of creating a new one. This mechanism makes string literals
efficient for frequently used strings.
SYNTAX:
String str = "Hello";
EXAMPLE PROGRAM:
}}
OUTPUT:-
2.STRING OBJECT
A string object is created using the new keyword, This approach explicitly creates a new object
in the heap memory, bypassing the string pool. Even if an identical string exists in the pool, a
new object is created. While this provides flexibility, it can be less memory-efficient since it
does not leverage the reuse feature of the string pool.
Key Characteristics of String Objects:
EXAMPLE PROGRAM
}}
OUTPUT:-
Java's memory management system is designed to ensure efficient allocation, usage, and
reclamation of memory, which is critical for applications. Among its memory areas, heap
memory plays a central role in storing objects, including their associated data and metadata.
Heap memory is a runtime memory area that the Java Virtual Machine (JVM) uses to allocate
memory for all Java objects and class instances. It is part of the JVM's larger memory
model and is shared across all threads in a Java application. Heap memory is dynamic, meaning
objects are created and destroyed during program execution.
In Java, when an object is created, it resides in the heap memory, which is dynamically
allocated at runtime. Each object in the heap is structured in a way that includes both its data and
additional information used by the JVM. This detailed explanation delves into the components,
memory layout, and lifecycle of an object in heap memory.
STRING METHODS
length()
charAt(int index)
substring(int beginIndex, int endIndex)
toLowerCase()
toUpperCase()
trim()
replace(char oldChar, char newChar)
equals(Object anotherString)
equalsIgnoreCase(String anotherString)
contains(CharSequence sequence)
Length()
The length() method is one of the most frequently used methods in the String class in Java. It
returns the number of characters present in the string, including spaces, punctuation, and
any other characters. This method does not require any arguments, and it returns an integer
value representing the total length of the string.
Key Points:
The method returns the total number of characters, including whitespace and
special characters.
It is a non-static method, meaning it can be called only on an instance of the String class.
It does not count null or empty strings, but rather the actual content within a String.
EXAMPLE PROGRAM
OUTPUT:-
Length of str1: 12
Length of str2: 4
charAt()
The charAt(int index) method is a fundamental method in the String class of Java. It is used to
retrieve a single character from a string at the specified position (index). The index is zero-
based, meaning the first character of the string is at index 0, the second at index 1, and so on.
This method returns a char value, representing the character at the given index.
Key Points:
Returns a char: The method returns a single character (char) at the specified index.
Indexing starts from 0: In Java strings, indexing starts at 0, so the first character is
at position 0, the second at position 1, and so on.
Throws StringIndexOutOfBoundsException: If the provided index is negative
or greater than or equal to the length of the string, it throws an exception.
EXAMPLE PROGRAM
OUTPUT:-
Character at index 3: l
substring()
The substring(int beginIndex, int endIndex) method is part of the String class in Java and is used
to extract a portion of a string from a given starting index (beginIndex) to an ending index
(endIndex). This method is very useful when you want to work with a specific section of a string,
such as extracting a word, sentence, or part of a path.
Key Points:
Start Index (beginIndex): The index where the substring begins, inclusive. It is the
first position of the substring in the original string.
End Index (endIndex): The index where the substring ends, exclusive. The character
at this position is not included in the resulting substring.
Zero-based Index: Both beginIndex and endIndex are zero-based. The first character
in the string has index 0, the second character has index 1, and so on.
StringIndexOutOfBoundsException: If the indices are out of range (negative or
greater than the string length), it throws a StringIndexOutOfBoundsException.
EXAMPLE PROGRAM
OUTPUT:-
Year: 2024
Month: 11
Day: 26
toLowerCase()
The toLowerCase() method in Java is used to convert all the characters in a given string to
lowercase. This method is part of the String class, which provides a wide range of useful
methods for string manipulation. It is a very commonly used method, particularly for case-
insensitive operations such as comparing strings, formatting input, or processing user data.
Key Points:
EXAMPLE PROGRAM
OUTPUT:-
toUpperCase()
The toUpperCase() method in Java is a built-in method provided by the String class that converts
all the characters in a given string to uppercase. This method is often used when you need to
format text for uniform display, case-insensitive comparison, or when transforming user input for
processing.
EXAMPLE PROGRAM
OUTPUT:-
trim()
The trim() method in Java is a built-in method of the String class that removes leading and
trailing whitespace from a string. This method is commonly used to clean up user input or text
data that may have extra spaces at the beginning or end, which are usually unnecessary for
comparison or display purposes.
Whitespace Removal: The trim() method removes any space characters (such as
spaces, tabs, and newline characters) from the beginning and end of a string, but does not
affect the spaces in the middle of the string.
Does Not Modify the Original String: Like other string methods, trim() does not
change the original string because strings in Java are immutable. Instead, it returns a new
string with the whitespace removed.
EXAMPLE PROGRAM
String[] usernames = {" javaMaster ", " java ", "developer ", " javaMaster"};
} else {
OUTPUT;-
The replace() method in Java is a part of the String class, and it is used to replace occurrences of
a specific character in a string with a new character. The method takes two arguments:
This method is useful for modifying strings, such as replacing certain characters with another
character or adjusting text before processing or displaying it.
Does Not Modify the Original String: Strings in Java are immutable, which
means the replace() method does not change the original string. Instead, it returns a new
string with the desired replacements.
Returns a New String: The method returns a new string in which all occurrences of
the specified character are replaced by the new character.
EXAMPLE PROGRAM
String sentence = "Java is an awesome programming language, but Java can be difficult!";
OUTPUT:-
Original Sentence: Java is an awesome programming language, but Java can be difficult!
Censored Sentence: **** is an awesome programming language, but **** can be difficult!
equals(Object anotherString)
The equals(Object anotherString) method in Java is used to compare two strings for equality. It
checks if the content of the string (the sequence of characters) is the same between two string
objects, not just their reference memory location.
Returns a Boolean: This method returns true if the two strings are exactly the same
(case-sensitive), and false if they are not.
String Comparison: Unlike ==, which compares memory references (addresses) of
objects, the equals() method compares the actual characters in the strings.
EXAMPLE PROGRAM
System.out.println(isEqual);
OUTPUT:-
False
equalsIgnoreCase(String anotherString)
The equalsIgnoreCase(String anotherString) method in Java is a part of the String class, and it is
used to compare two strings for equality while ignoring case differences. This means that the
method will return true if the strings are the same, regardless of whether the characters are
uppercase or lowercase.
insensitive, making it useful when you need to compare strings without caring about case
sensitivity.
EXAMPLE PROGRAM
System.out.println(isEqual);
OUTPUT:-
True
contains(CharSequence sequence)
The contains(CharSequence sequence) method is part of the String class in Java, and it is used to
check if a given sequence of characters exists within a string. This method returns a boolean
value (true or false) depending on whether the specified sequence of characters (substring) is
present in the string or not.
EXAMPLE PROGRAM
System.out.println(containsJava);
OUTPUT:-
True
1. Thread Safety
2. Performance
3. Use Case
4. Synchronization
5. Constructor
StringBuilder: StringBuilder() or StringBuilder(int capacity).
StringBuffer: StringBuffer() or StringBuffer(int capacity).
Explanation: Both classes offer constructors that allow you to specify an initial capacity
for the underlying character array. However, StringBuffer adds synchronization features,
while StringBuilder does not.
6. Method Behavior
7. Memory Overhead
8. Mutability
9. API Availability
EXAMPLE PROGRAM
sb.append("Hello");
sbf.append("World");
});
thread1.start();
try {
thread1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}}}
OUTPUT:-
Detailed Features:
The Math class contains methods for performing basic arithmetic operations such as
addition, subtraction, multiplication, division, and more.
It also provides methods for more complex operations such as exponentiation (pow()),
logarithms (log()), trigonometric functions (sin(), cos(), tan()), and rounding operations
(round(), ceil(), floor()).
The Math class also includes a random number generator through the
Math.random() method, which returns a pseudo-random number between 0.0 and 1.0.
Constants: The Math class has constants such as Math.PI (the value of Pi) and
Math.E (Euler's number), which are useful in scientific calculations.
EXAMPLE PROGRAM
OUTPUT:-
The Scanner class, located in the java.util package, is one of the most commonly used classes
for getting input from users. It allows reading various types of data such as strings, integers,
floats, booleans, etc. The Scanner class can be used to read input from different sources such as
keyboard input, files, or streams.
Detailed Features:
Input Handling: Scanner simplifies handling user input in various formats. It reads
tokens (chunks of text), interprets them into specific data types, and allows you to process
the data accordingly.
Reading Different Data Types: The Scanner class offers methods such as
nextInt(), nextDouble(), nextLine(), and nextBoolean() to read integers, doubles, strings,
and booleans, respectively.
Delimiters: You can specify delimiters using the useDelimiter() method, which allows
the Scanner to split input based on specific characters or patterns.
Error Handling: The Scanner class also allows you to handle invalid input and
provides methods like hasNext() to check if more tokens are available.
EXAMPLE PROGRAMS
import java.util.Scanner;
System.out.println("Hello, " + name + ". You are " + age + " years old.");
scanner.close();
OUTPUT:-
The Random class is part of the java.util package and is used to generate pseudo-random
numbers in Java. Unlike Math.random(), which generates a random number between 0.0 and 1.0,
the Random class provides more flexibility by allowing the generation of random integers,
doubles, booleans, and more within a specified range.
Detailed Features:
Random Integer Generation: The nextInt() method can generate random integers.
You can specify a range for the random integer using nextInt(n), which generates a value
between 0 (inclusive) and n (exclusive).
Random Float and Double: nextFloat() and nextDouble() generate random
floating-point numbers. The nextDouble() method, for example, generates a number
between 0.0 (inclusive) and 1.0.
Random Boolean: The nextBoolean() method generates a random boolean value
(either true or false).
Seeded Random Numbers: You can provide a seed value to the Random
constructor for generating repeatable random sequences.
EXAMPLE PROGRAM
import java.util.Random;
}}
OUTPUT:-
Random Integer: 45
Random Boolean: false
Random Double: 0.16687296510690963
The Logger class is part of the java.util.logging package and is used for logging messages
during program execution. It is a powerful tool for tracking and debugging Java applications by
allowing developers to log information, warnings, errors, and other types of messages with
different severity levels.
Detailed Features:
Logging Levels: The Logger class supports multiple logging levels, such as INFO,
WARNING, SEVERE, CONFIG, FINE, and FINER. Each level indicates the severity of
the logged message.
Logging Handlers: You can configure logging handlers that determine where the log
messages are output (console, file, etc.).
Configurable Log Format: The format of the logged messages can be customized
to include information such as timestamps, log levels, and message details.
Exception Logging: You can log exceptions with detailed stack traces to facilitate
easier debugging.
EXAMPLE PROGRAM
import java.util.logging.*;
logger.setLevel(Level.ALL);
try {
int result = 10 / 0;
} catch (ArithmeticException e) {
}
}
OUTPUT:-
Exception handling allows programs to handle errors gracefully without crashing, providing a
better user experience.
EXAMPLE PROGRAM:-
In Java, a variable is a container or a memory location used to store data that can be accessed
and manipulated throughout the execution of a program. Each variable in Java has a name, a data
type, and a value. The data type defines the kind of data a variable can hold, such as an integer, a
floating-point number, or a string. The name, also known as the identifier, is used to refer to that
specific piece of data within the program. Java is a strongly-typed language, meaning each
variable must be declared with a specific type before it is used. Once declared, a variable can be
initialized with a value and can be changed or updated as needed.
Variables are essential in programming as they allow you to store information that can change
over time, such as the user's input, the result of a calculation, or the state of an application. In
Java, variables play a critical role in controlling the flow of data within programs.
Java variables are categorized based on their scope, lifetime, and memory allocation. The three
main types of variables in Java are:
1. Local Variables
2. Instance Variables
1. LOCAL VARIABLES
Local variables are variables that are declared inside methods, constructors, or blocks. They are
only accessible within the method, constructor, or block where they are declared. Local variables
do not have default values, so they must be explicitly initialized before use. Once the method or
block finishes execution, the local variable is destroyed, making its lifetime very limited.
Local variables are typically used for temporary data storage within methods. They allow for
efficient memory management because they only exist during the execution of the method or
block in which they are declared.
EXAMPLE PROGRAM
System.out.println(x);
OUTPUT:-
10
2. INSTANCE VARIABLES
Instance variables are variables declared inside a class but outside of any method, constructor, or
block. These variables are associated with instances of the class (objects). Each object created
from the class has its own copy of the instance variables, which means that different objects can
hold different values for these variables.
Instance variables are initialized with default values if no explicit initialization is provided. For
example, an integer instance variable will have a default value of 0. These variables are essential
for storing the state of an object.
EXAMPLE PROGRAM
int number=53;
obj.display();
}}
OUTPUT:-
Class variables, also known as static variables, are declared with the static keyword. Unlike
instance variables, class variables are shared by all objects of the class. This means that a single
copy of the static variable exists, regardless of how many instances of the class are created. Static
variables are often used to store properties that are common to all objects of the class.
Static variables can be accessed directly through the class name, or through any instance of the
class. These variables are initialized when the class is loaded into memory, and they exist for the
lifetime of the program.
EXAMPLE PROGRAM
count++;
}
obj1.increment();
obj2.increment();
}}
OUTPUT:-
Count: 2
THIS KEYWORD
In Java, the this keyword is a reference variable that refers to the current instance of the class. It
is used within instance methods or constructors to refer to the current object of the class. The this
keyword helps to differentiate between instance variables and local variables or parameters with
the same name. It can also be used to invoke instance methods and constructors from the current
object.
EXAMPLE PROGRAM
this.accountHolderName = accountHolderName;
this.balance = initialDeposit;
this(accountHolderName, 0.0);
if (amount > 0) {
this.balance += amount;
return this;
this.balance -= amount;
} else {
System.out.println("Insufficient funds.");
return this;
account.deposit(500.0).withdraw(200.0).displayAccountDetails();
account2.deposit(200.0).withdraw(50.0).displayAccountDetails();
}}
OUTPUT:-
TYPECASTING IN JAVA
Typecasting is the process of converting one data type to another in Java. It is particularly useful
when dealing with different data types and ensuring that operations are performed with
compatible types. Typecasting can be done either implicitly (automatically) or explicitly
(manually).
Implicit typecasting, also known as widening, happens automatically when a smaller data type
is assigned to a larger data type. In this case, no explicit cast is needed because Java
automatically converts the value to the appropriate type. This happens when there is no loss of
data or precision, and the conversion is safe.
EXAMPLE PROGRAM
}}
OUTPUT:-
Explicit typecasting, also known as narrowing, occurs when a larger data type is converted
into a smaller data type. This requires the programmer to manually cast the data type using
parentheses. Narrowing may result in a loss of data, so it needs to be done carefully. If the value
being converted is too large to fit in the smaller data type, it may cause an overflow or other
unexpected behavior.
EXAMPLE PROGRAM
double pi = 3.14159;
}}
OUTPUT:-
CONSTRUCTORS IN JAVA
A constructor in Java is a special method that initializes an object when it is created. Unlike
normal methods, constructors have a unique purpose: they prepare an object for use by
initializing its state (i.e., assigning values to its instance variables or performing setup tasks). The
name of a constructor must match the name of its class, and it cannot have a return type.
1. Name Matches Class: The name of the constructor must be the same as the class
name.
2. No Return Type: Constructors do not return any value, not even void.
3. Automatic Invocation: A constructor is called automatically when an object is
created using the new keyword.
4. Initialization: Constructors are primarily used to initialize the data of an object.
5. No Inheritance: Constructors are not inherited, but a subclass can call a superclass's
constructor using super().
6. Overloading: A class can have multiple constructors with different parameter lists, a
concept known as constructor overloading.
1. Default Constructor
2. Parameterized Constructor
3. Copy Constructor
DEFAULT CONSTRUCTOR
EXAMPLE PROGRAM
class IndianRupeeWallet {
String ownerName;
int rupeeBalance;
public IndianRupeeWallet() {
rupeeBalance = 500;
}}
wallet2.displayWalletDetails();
}}
OUTPUT:-
PARAMETERIZED CONSTRUCTOR
1. Accepts Parameters:
o A parameterized constructor takes arguments that are used to initialize the object's
fields. These parameters can be of any data type, including primitive types or
objects.
2. Facilitates Object Customization:
o It allows the creation of objects with specific, unique values instead of relying on
default or predefined values.
3. Avoids Redundancy:
o Directly assigns values to the attributes at the time of object creation, eliminating
the need for setter methods.
4. Ensures Complete Initialization:
o Enforces the creation of fully initialized objects by requiring all necessary values
at the time of instantiation.
EXAMPLE PROGRAM
class LibraryBook {
String title;
String author;
int pages;
this.title = title;
this.author = author;
this.pages = pages;
System.out.println("--------------------------");
book1.displayDetails();
book2.displayDetails();
book3.displayDetails();
OUTPUT:-
COPY CONSTRUCTOR
A copy constructor in Java is a special constructor used to create a new object as a copy of
an existing object. It duplicates the fields of an existing object into a new object, providing a
convenient way to clone or replicate objects while maintaining their independence.
EXAMPLE PROGRAM
class BankAccount {
String accountHolder;
double balance;
public BankAccount(String accountHolder, double balance) {
this.accountHolder = accountHolder;
this.balance = balance;
}
public BankAccount(BankAccount other) {
this.accountHolder = other.accountHolder;
this.balance = other.balance;
}
public void displayDetails() {
System.out.println("Account Holder: " + accountHolder);
System.out.println("Balance: ₹" + balance);
}
public void withdraw(double amount) {
if (amount <= balance) {
balance -= amount;
System.out.println("Withdrawal of ₹" + amount + " successful.");
} else {
System.out.println("Insufficient funds!");
}}}
OUTPUT:-
METHODS IN JAVA
In Java, a method is a block of code designed to perform a particular task. It is one of the
building blocks of Java programs, allowing for code reusability, abstraction, and organization.
Methods are defined inside a class and can be called upon to perform operations on data or to
carry out specific actions.
Java’s object-oriented nature encourages the use of methods to define behaviors associated with
objects. Methods allow programmers to write modular, reusable, and readable code. They can be
invoked to carry out tasks like calculations, manipulating object states, or controlling program
flow.
Key Components of a Method in Java:
1. Method Declaration:
o The method declaration includes the access modifier, return type, method
name, and parameter list. These are the essential components of the method.
2. Access Modifier:
o The access modifier determines the visibility of the method within the class or
across the program. Common access modifiers include:
public: The method is accessible from anywhere.
private: The method is accessible only within the class.
protected: The method is accessible within the package and by subclasses.
Default (no modifier): The method is accessible within the package.
3. Return Type:
o The return type specifies the type of value the method will return. It can be a
primitive type (like int, float, char), an object (like String, ArrayList), or void if
the method doesn't return anything.
4. Method Name:
o The method name should follow Java naming conventions (camelCase) and
should describe the task the method performs.
5. Parameters (Optional):
o Methods may accept one or more parameters that act as input to the method.
These are placed inside the parentheses and allow data to be passed into the
method for processing.
6. Method Body:
o The method body contains the logic or code that defines the behavior of the
method. It is enclosed in {}.
Instance Method
Static Method
Abstract Method
Final Method
INSTANCE METHOD
Instance methods are commonly used to define behaviors or actions that depend on the state of
an object. When a new object of a class is created, an instance method can be called to perform
some operation related to that particular object’s state.
1. When the behavior depends on the state of the object: Since instance
methods can access and modify instance variables, they are ideal when the behavior
needs to depend on the specific state of the object. For example, if a method calculates
the area of a circle, the radius (instance variable) of the specific circle object should be
used in the calculation.
2. When an action is tied to an individual object: If you need to perform actions
that are specific to an object rather than the class itself, an instance method is appropriate.
For instance, methods that simulate actions (e.g., a car starting, a person speaking) should
be instance methods, because these actions occur on individual objects.
3. When object-oriented principles are important: Instance methods help
encapsulate functionality in the class and are aligned with key object-oriented
programming principles, such as abstraction, inheritance, and polymorphism. They allow
you to structure behaviors specific to objects and help maintain the integrity of the
object's state.
returnType methodName(parameters) {
// method body
}
returnType: The type of value the method returns (or void if it doesn't return anything).
methodName: The name of the method.
parameters: A list of parameters the method takes (if any).
EXAMPLE PROGRAM
class Student {
String name;
int[] scores;
this.name = name;
this.scores = scores;
int total = 0;
for (int score : scores) {
total += score;
return name + " has passed with an average score of " + average;
} else {
return name + " has failed with an average score of " + average;
}}
student1.displayScores();
System.out.println(student1.checkPassFail());
student2.displayScores();
System.out.println(student2.checkPassFail());
}}
OUTPUT:-
STATIC METHOD
In Java, a static method is a method that belongs to the class rather than to instances of the
class (objects). This means that static methods can be called directly on the class itself without
the need to create an instance (object) of the class.
A static method can access only static variables and static methods within the class. It
cannot access instance (non-static) variables or instance methods because instance members
require an object to exist.
Static methods are typically used in situations where the method functionality is independent
The method performs a utility function that doesn’t depend on the state (or data) of any
particular object.
You want to perform operations that are the same across all instances of the class.
You need to create helper or utility methods that can be called without creating an object
of the class.
EXAMPLE PROGRAM
class TemperatureConverter {
OUTPUT:-
25.0 °C is 77.0 °F
77.0 °F is 25.0 °C
25.0 °C is 298.15 K
298.15 K is 25.0 °C
77.0 °F is 298.15 K
298.15 K is 77.0 °F
ABSTRACT METHOD
In Java, an abstract method is a method that is declared without an implementation. It acts as
a blueprint for subclasses, which are required to provide a specific implementation for the
method. Abstract methods are used in abstract classes or interfaces. The key idea behind abstract
methods is to define a contract that subclasses must adhere to, ensuring that certain
functionality is implemented in all subclasses, while still leaving the specifics of that
implementation to the subclasses.
EXAMPLE PROGRAM
task1.performTask();
task2.performTask();
task3.performTask();
OUTPUT:-
FINAL METHOD
A final method is a method that cannot be overridden by any subclass. This guarantees that
the implementation of the method in the base class will be used without modification, no matter
what class inherits from it. In other words, once a method is declared as final, it cannot be
modified by subclass methods.
EXAMPLE PROGRAM
class PasswordManager {
this.password = password;
if (password.length() < 8) {
return false;
if (!password.matches(".*[A-Z].*")) {
if (!password.matches(".*[0-9].*")) {
return false;
return true;
super(password);
super(password);
}}
}}
OUTPUT:-
Memory management in Java is crucial for efficient execution of programs. Understanding how
the Java Virtual Machine (JVM) manages memory through the Heap, Stack, and Method
Area is essential for writing optimal Java applications. Each memory area is designed for
specific purposes and plays a significant role in the performance and behavior of a program.
Heap
Stack
Method Area
HEAP AREA
The Heap is the region of memory used for dynamic memory allocation. It is where
objects and arrays are stored. When you use the new keyword to create an object, the memory
for that object is allocated in the heap. Similarly, arrays, whether they contain primitive data
types or objects, are also stored in the heap. Unlike the stack, which is used for temporary
memory, the heap is used for long-lived objects that might need to be accessed across
different parts of the program.
Dynamic Allocation: The size of the heap is not fixed. Objects can be dynamically
created at runtime, and the heap grows as needed to accommodate the new objects.
Garbage Collection: The heap is managed by the Garbage Collector (GC).
Objects that are no longer referenced by any part of the program become garbage and
are automatically removed by the GC to free up memory.
Use Cases:
When you create a new object or array (e.g., new String()), the memory for that object is
allocated in the heap.
Objects in the heap can be shared across methods and even different threads.
The size of the heap can be controlled via JVM options (-Xms for initial heap size and -
Xmx for maximum heap size).
The heap is garbage-collected, meaning unused memory is automatically reclaimed
to avoid memory leaks.
STACK AREA
The Stack is used for temporary memory allocation. It stores local variables,
method call frames, and return addresses. Every time a method is invoked, a new stack
frame is created to hold the method's local variables and execution details. When the method
execution completes, its stack frame is popped off the stack, freeing the memory.
Last-In, First-Out (LIFO) Structure: The stack follows the LIFO order. When a
method is called, its stack frame is pushed onto the top of the stack, and once the method
returns, its frame is popped from the stack.
Automatic Deallocation: Variables stored in the stack are automatically deallocated
when the method completes.
Use Cases:
The stack stores data that is only needed for a specific method execution, such as local
variables and parameters.
Stack memory is used for recursion and method calls.
METHOD AREA
The Method Area (or Metaspace in modern versions of Java) is a special region of memory
where class-level data is stored. This includes the bytecode of classes, method definitions,
static variables, and constant pools. Unlike heap and stack memory, the method area is shared
Class-Level Data: It holds information about loaded classes, including class metadata,
method and field data, and constant values.
Runtime Constant Pool: This area also stores constants and references, such as
string literals and method references, used by the class during runtime.
Use Cases:
The method area is crucial for the JVM class loading process. Whenever a class is
loaded into memory, its metadata and bytecode are stored in the method area.
It contains static variables shared by all instances of a class and compiled
The size of the method area is dynamic in modern Java, and in the case of Metaspace, it
grows automatically.
In earlier versions of Java, the method area had a fixed size (managed by the -
XX:MaxPermSize option).
Conditional statements in Java are used to execute specific blocks of code based on a given
condition or expression's evaluation. They allow the program to make decisions and perform
different actions depending on whether certain conditions are met. These statements are
fundamental for controlling the flow of execution and are part of decision-making logic in
programming.
There are several types of conditional statements in Java, each serving different purposes
depending on the complexity and requirements of the program.
If
If…Else
Nested If
Switch
IF
The if statement in Java is a decision-making construct used to execute a particular block of code
only when a specific condition is satisfied. It evaluates a condition, and if that condition is true,
the block of code within the if statement is executed. If the condition is false, the program simply
bypasses the block and continues with the rest of the code. This provides a means for a program
to make decisions based on dynamic inputs or states.
SYNTAX:
if (condition) {
EXAMPLE PROGRAM
} else {
}
}
OUTPUT:-
IF…Else
In Java, the if-else statement is a control flow statement used to execute one block of code
among two alternatives, depending on whether a specified condition evaluates to true or false. It
allows the program to make decisions, providing a way to execute different pieces of code based
on different conditions.
The basic idea behind if-else is simple: if a condition evaluates to true, execute the code inside
the if block; otherwise, execute the code inside the else block. This makes it a fundamental
control structure for branching logic in Java programs.
SYNTAX
if (condition) {
} else {
EXAMPLE PROGRAM
letter == 'a' || letter == 'e' || letter == 'i' || letter == 'o' || letter == 'u') {
} else {
OUTPUT:-
B is a Consonant.
NESTED IF
A nested if statement in Java is a logical control structure where one if statement is placed
inside another. This structure is particularly useful for handling decision-making scenarios that
depend on multiple conditions evaluated sequentially. Each inner if block is processed only when
the outer if condition is true, making nested if statements a powerful tool for implementing
hierarchical or tiered logic.
SYNTAX
if (condition1) {
// Outer if block
if (condition2) {
// Inner if block
} else {
} else {
EXAMPLE PROGRAM
if (goodWeather) {
if (isFit) {
} else {
} else {
} }}
OUTPUT:-
SWITCH
The switch statement in Java is a versatile decision-making control structure that simplifies
handling multiple conditions. It evaluates a single expression and matches its result against a list
of predefined values called cases. When a match is found, the corresponding block of code
executes. This structure is a clean, concise alternative to multiple if-else conditions, particularly
when testing a variable for equality against several possible values.
SYNTAX:-
switch (expression) {
case value1:
case value2:
break;
default:
EXAMPLE PROGRAM:-
int dayNumber = 7;
String dayType;
String dayName;
switch (dayNumber) {
case 1:
dayName = "Monday";
dayType = "Weekday";
break;
case 2:
dayName = "Tuesday";
dayType = "Weekday";
break;
case 3:
dayName = "Wednesday";
dayType = "Weekday";
break;
case 4:
dayName = "Thursday";
dayType = "Weekday";
break;
case 5:
dayName = "Friday";
dayType = "Weekday";
break;
case 6:
dayName = "Saturday";
dayType = "Weekend";
break;
case 7:
dayName = "Sunday";
dayType = "Weekend";
break;
default:
dayType = "Unknown";
}}
OUTPUT:-
Day: Sunday
Type: Weekend
LOOPS IN JAVA
In Java, loops are fundamental constructs that enable a program to execute a block of code
multiple times, based on specific conditions. This ability to repeat tasks reduces code duplication
and promotes efficiency by eliminating the need for manually writing repetitive code. Loops are
essential when working with large datasets or performing tasks that require repetitive actions,
such as processing user input or iterating through elements in a collection. By allowing code to
run continuously or a fixed number of times, loops make Java programs more concise, readable,
and maintainable.
For Loop
While loop
Do…while loop
For Loop
The for loop in Java is one of the most commonly used loops because of its clear and compact
structure, making it ideal for scenarios where the number of iterations is known in advance. It’s a
control flow statement used to repeat a block of code multiple times. The loop works by
executing the block of code as long as the specified condition evaluates to true. The loop
automatically handles the initialization, condition checking, and update, reducing the complexity
of the code.
SYNTAX
Initialization:
Condition:
The loop will continue to run as long as the condition evaluates to true.
After each iteration, the condition is checked before executing the loop body again. If the
condition becomes false, the loop terminates.
For example, i < 10; ensures that the loop runs as long as i is less than 10.
Update:
EXAMPLE PROGRAM
int n = 10;
first = second;
second = next;
}}
OUTPUT:-
WHILE LOOP
A while loop allows repeated execution of a statement or block of code based on a boolean
condition. The key feature of the while loop is that it evaluates the condition before entering the
loop body. If the condition is true, the loop body is executed; if the condition evaluates to false,
the loop terminates, and the program continues with the next statement after the loop.
This loop is ideal when you need to perform an action repeatedly but don't know how many
times the action should be performed ahead of time. It keeps running until the condition specified
within the loop becomes false.
SYNTAX
while (condition) {
// Code to be executed
condition: The condition is evaluated before each iteration. If it returns true, the loop
will continue. If it evaluates to false, the loop terminates.
Code Block: This is the block of code that will be executed repeatedly as long as the
condition is true.
EXAMPLE PROGRAM
import java.util.Scanner;
int number = 0;
while (true) {
if (scanner.hasNextInt()) {
number = scanner.nextInt();
if (number < 0) {
} else {
break; }
} else {
scanner.next();
} }
long factorial = 1;
int i = 1;
factorial *= i;
i++; }
}}
OUTPUT:-
DO…WHILE LOOP
The do-while loop in Java is a variant of the while loop. It is used when you want to execute a
block of code at least once, regardless of the condition being true or false. Unlike the while loop,
where the condition is checked before entering the loop, the do-while loop checks the condition
after executing the block of code. This guarantees that the code inside the loop is executed at
least once.
SYNTAX:-
do {
do:
The curly braces {} define the body of the do loop. All the statements inside the braces
will be executed in each iteration.
These statements can be a single statement or multiple statements that you want to repeat.
while:
After the do block, the while keyword is used to specify the condition that determines if
the loop will continue executing.
The condition inside the parentheses is evaluated after executing the code inside the do
block.
(condition):
The condition is a Boolean expression (i.e., an expression that evaluates to true or false).
If the condition is true, the loop will execute again (i.e., the code inside the do block will
be executed again).
If the condition is false, the loop will terminate, and the program control will move to the
next statement following the do-while loop.
Semicolon (;):
The while (condition) part ends with a semicolon ;. This semicolon signifies the end of
the loop condition statement.
EXAMPLE PROGRAM
int counter = 1;
do {
counter++;
}}
OUTPUT:-
Jump statements in Java are powerful tools that control the flow of execution in your programs.
They allow you to break out of loops, skip certain parts of the code, or exit from methods when
certain conditions are met. This control flow is essential for creating efficient, clean, and
readable code, especially when handling complex logic or managing repetitive tasks within
loops.
1. break statement
2. continue statement
1.BREAK STATEMENT
The break statement in Java is a control flow mechanism that allows you to exit a loop or
switch statement prematurely, which can significantly optimize the flow of execution in
certain scenarios. By using break, you can stop further iterations of a loop or prevent code from
falling through multiple switch cases, saving unnecessary computations or ensuring that only the
relevant case in a switch statement is executed.
1. In Loops
The break statement can be used inside any type of loop, including for, while, and do-while
loops. When the break is executed, the loop is immediately terminated, and the control flow is
transferred to the first statement after the loop. This is useful when the loop needs to stop under
certain conditions, even if the loop's termination condition hasn't been met yet.
For example, imagine you have a loop that is designed to search through a list for a specific item.
As soon as the item is found, there’s no reason to continue searching, and the break statement
allows you to exit the loop immediately.
2. In Switch Statements
In a switch statement, the break statement serves to terminate the case block and exit the
switch structure. Without the break, Java will execute the code for the current case and "fall
through" to execute the code of the next case, even if the case conditions do not match. The
break statement ensures that once the code for a specific case has been executed, no further cases
will be checked.
Exiting Loops Early: When a condition inside a loop has been satisfied, and there’s
no need to continue iterating. This is commonly used in search or validation operations.
Preventing Fall-through in Switch Statements: In switch blocks, break
prevents the default fall-through behavior, ensuring that only one case block is executed.
EXAMPLE PROGRAM
if (numbers[i] == 20) {
} }}
OUTPUT:-
Checking number: 5
Checking number: 10
Checking number: 15
Found 20! Breaking the loop...
2.CONTINUE STATEMENT
The continue statement in Java is used to skip the current iteration of a loop and proceed
with the next iteration of the loop. When the continue statement is encountered, the remaining
part of the loop body is skipped for the current iteration, and the loop moves to the next cycle.
This statement is useful when you want to skip over certain conditions and continue with the
loop's logic.
The continue statement can be used in for, while, and do-while loops. Depending on
where it is used in the loop, it causes the loop to skip the current iteration and move to the
next cycle.
In a for Loop:
When used in a for loop, the continue statement skips the current iteration and proceeds to
the increment part of the loop before checking the loop's condition again. Essentially, it skips
over the remaining statements in the loop body for that particular iteration.
You want to skip certain conditions but still continue looping through the rest of the
iterations.
It helps reduce the need for deep nested condition checks inside loops and can make the
code cleaner and more efficient by avoiding unnecessary operations.
EXAMPLE PROGRAM
ARRAYS IN JAVA
An array in Java is essentially a container or data structure that holds multiple elements
of the same data type under a single variable name. These elements are stored in
consecutive memory locations, and each element can be accessed via its index. Arrays in
Java can hold either primitive types like integers, floats, and booleans, or reference types like
objects and strings.
Arrays are fixed in size, which means once you declare and instantiate an array, its size cannot
be changed during runtime. You define the number of elements it can store at the time of
creation. Arrays are ideal for cases where you need to work with a known and fixed
number of items.
While arrays offer several advantages, they also come with limitations, especially when
dealing with primitive data types like int, char, boolean, etc. These limitations can make
arrays less suitable in some scenarios:
1. Fixed Size:
o One of the most significant drawbacks of arrays in Java is their fixed size. Once
an array is created with a specified size, it cannot be resized. If the size of the
collection changes dynamically, you would need to create a new array, copy data
over, and adjust its size. This rigidity makes arrays less flexible for certain
applications, like handling unknown amounts of data.
2. No Built-in Dynamic Resizing:
o Arrays of primitive types can be memory-inefficient when the array size is set
too large but the number of valid entries is small. For instance, if you allocate an
array of 1000 integers, but only use 100, you are wasting memory. Dynamic data
structures like ArrayList or LinkedList are more memory-efficient because they
grow and shrink as needed.
5. No Built-in Methods for Common Operations:
o Arrays lack the built-in methods that make it easier to perform common
operations, such as adding, removing, or resizing elements. While arrays allow
direct access to their elements using indices, you must implement your own logic
for tasks such as element addition, deletion, and searching, which can be
cumbersome and error-prone.
6. Multi-Dimensional Array Complexity:
1. Linear Storage:
o The elements in a 1D array are arranged in a straight line (linear sequence). This
means that the elements are stored sequentially in memory, making it easy to
access each element using an index.
2. Fixed Size:
o When you create a 1D array in Java, you must define its size upfront. Once the
size is set, it cannot be changed. This is because arrays in Java are fixed in size,
and their memory allocation is contiguous.
3. Zero-Based Indexing:
o In Java, arrays are indexed starting at 0. So, the first element of the array is
accessed using index 0, the second element with index 1, and so on. This makes
the last element of a 1D array accessible via array.length - 1.
4. Type Consistency:
o All elements in a single-dimensional array must be of the same data type. This
ensures that memory allocation is contiguous and efficient.
5. Direct Memory Access:
o Each element in the array is stored at a specific memory location, allowing for
direct access using its index. This gives arrays an edge in terms of performance,
particularly when accessing or modifying elements.
Storing a List of Items: If you have a list of values that belong to the same category,
such as the ages of a group of people, the scores of students in an exam, or even a
collection of product prices, a 1D array is the most straightforward approach.
Data Representation: If you’re dealing with a simple dataset where each element is
distinct but of the same type, such as a set of unique IDs, names, or sensor readings, a 1D
array provides a quick way to store and retrieve those elements.
Efficient Iteration: For operations like summing, finding the maximum or minimum,
or performing other aggregate functions, iterating over the elements of a 1D array is very
efficient due to its linear structure.
Quick Access: When you need fast access to specific elements by their position, such
as looking up an element by index, a 1D array gives constant-time access (O(1)
complexity).
One of the reasons why 1D arrays are so efficient is the way they are stored in memory. When
you declare an array, Java allocates a contiguous block of memory for all the elements. This is
different from other data structures (like linked lists), where elements may be scattered across
memory.
Each array element can be accessed directly using the index. If the starting address of the array is
known, the address of any element can be calculated by adding the index multiplied by the size
of the element to the base address. This is why array indexing is so fast—it requires no
SYNTAX:-
1. Declaration:
dataType[] arrayName;
Explanation:
This step defines an array variable named arrayName of the specified dataType. The array is
only declared here and does not hold any values until memory is allocated. The dataType can be
any primitive type (e.g., int, float, char) or a reference type (e.g., String, Object).
2. Instantiation:
Explanation:
This combines both the declaration and instantiation in a single line. It declares an array
arrayName of type dataType, allocates memory for it, and defines its size in one step. This is
commonly used when you know the size of the array ahead of time and want to initialize it in a
single line.
EXAMPLE PROGRAM
int sum = 0;
int count = 0;
if (numbers[i] % 2 == 0) {
sum += numbers[i];
count++;
if (count > 0) {
} else {
System.out.println("No even numbers found in the array.");
} }}
OUTPUT:-
A 2D array in Java is an array whose elements are arrays themselves. This means that each
element in the 2D array is a reference to another array, which can be accessed via two indices:
one for the row and one for the column. The structure is similar to a matrix, where each row is an
array, and the columns are the individual elements within that row.
1. Fixed Size:
o Once a 2D array is created, its size cannot be changed. The number of rows and
columns must be specified during initialization and cannot be modified later.
2. Contiguous Memory Allocation:
o A 2D array is stored in a contiguous block of memory. The array consists of an
array of arrays, and each inner array represents a row. This layout allows for
efficient access to elements based on their row and column indices.
3. Indexed Access:
o Elements in a 2D array are accessed by two indices: one for the row and one for
the column. This indexing provides direct access to any element in constant time.
4. Row-Column Structure:
o The array is organized into rows and columns. It is essentially a collection of data
items arranged in a grid format. This makes it suitable for representing data in a
tabular or matrix-like structure.
5. Default Values:
o If a 2D array is declared but not explicitly initialized, the elements will be
automatically assigned default values based on the data type. For numeric types,
the default value is 0, and for reference types like objects or strings, the default
value is null.
6. Memory Efficiency:
o 2D arrays are memory efficient when the size is known beforehand and does not
change, as the elements are stored in a contiguous memory block. However, the
size is static, and there is no flexibility to add or remove elements dynamically.
7. Multi-Dimensional Arrays:
o Java supports arrays with more than two dimensions, referred to as multi-
dimensional arrays. These arrays extend the concept of 2D arrays to higher
dimensions, allowing the representation of more complex data structures.
1. Tabular Data:
o 2D arrays are best suited for storing tabular data where the information is
organized into rows and columns. This is useful when dealing with data that
follows a grid-like structure, such as schedules, records, or spreadsheets.
2. Matrix Operations:
o 2D arrays are commonly used for matrix representation, where mathematical
operations such as addition, subtraction, multiplication, and finding the inverse
can be easily performed on them.
3. Grid-based Systems:
o When you need to represent a grid or a board in applications like games (e.g.,
chess, tic-tac-toe) or simulations (e.g., terrain mapping, maze generation), 2D
arrays are an ideal choice.
4. Image Representation:
o 2D arrays are frequently used to represent images, where each pixel or cell in the
array corresponds to an element of the image, allowing easy manipulation of pixel
data for operations like image processing or transformations.
5. Geographical Data:
o 2D arrays are effective for storing geographical data such as maps, where each
element in the array represents a geographic coordinate or an attribute of a
specific location.
6. Game Development:
o For board games or grid-based games, such as Sudoku or Minesweeper, 2D arrays
provide a straightforward way to store and manage game state in a grid structure.
7. Sorting and Searching in a Grid:
o 2D arrays can also be used for sorting and searching operations that involve data
organized in a grid or matrix format, where algorithms like row or column-based
sorting or searching are applied.
SYNTAX:-
Declaration:
dataType[][] arrayName;
dataType: Specifies the type of data the array will hold, such as int, double, String, or
even custom objects.
arrayName: The name you assign to the array variable, which will be used to reference
the array.
The declaration alone only defines the array's type and name but does not allocate memory for
the array's elements.
Instantiation: After declaring an array, the next step is to allocate memory for the array. This
is done by specifying the number of rows and columns the array will have.
This creates an array with the specified dimensions in memory, where each element is initialized
with a default value (e.g., 0 for numeric types or null for reference types).
Combined Declaration and Instantiation: In Java, you can declare and instantiate a 2D
array in one step by combining both processes:
EXAMPLE PROGRAM
int number = 5;
table[i][0] = i + 1;
} }}
OUTPUT:-
The foundation of OOPs lies in classes (blueprints that define objects) and objects (instances
of classes). Objects store attributes (data) and expose behaviors (methods), enabling developers
to create intuitive models of real-world systems. This approach improves the clarity of code by
organizing it into self-contained units.
Why OOPs?
1. Modularity: OOPs breaks down large systems into smaller, manageable modules.
4. Maintainability: Changes or updates can be made with minimal impact on the entire
system.
Encapsulation is about hiding the internal data and allowing controlled access via public
methods.
EXAMPLE PROGRAM:-
public class Product {
private String productName;
private double price;
private int stockQuantity;
public Product(String productName, double price, int stockQuantity) {
this.productName = productName;
this.price = price;
this.stockQuantity = stockQuantity;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
if (price > 0) {
this.price = price;
} else {
throw new IllegalArgumentException("Price must be positive");
}
}
public int getStockQuantity() {
return stockQuantity;
}
public void setStockQuantity(int stockQuantity) {
if (stockQuantity >= 0) {
this.stockQuantity = stockQuantity;
} else {
throw new IllegalArgumentException("Stock quantity cannot be negative");
}
}
public void displayProductInfo() {
System.out.println("Product: " + productName + " | Price: $" + price + " | In Stock: " +
stockQuantity);
}
}
Inheritance allows one class to inherit the properties and behaviors of another.
EXAMPLE PROGRAM:-
Polymorphism allows different classes to be treated as instances of the same class through
inheritance, with different behaviors.
EXAMPLE PROGRAM:-
Abstraction hides the complex reality while exposing only the essential parts of an object. This is
achieved using abstract classes or interfaces.
EXAMPLE PROGRAM:-
Constructor overloading is a technique to provide multiple ways of creating an object, each with
different parameters.
EXAMPLE PROGRAM:-
The this keyword refers to the current instance of the class, which is useful when differentiating
between instance variables and method parameters.
EXAMPLE PROGRAM:-
The super keyword helps in accessing the parent class's methods and constructors.
EXAMPLE PROGRAM:-
Static members (fields or methods) belong to the class rather than any individual object, meaning
they are shared across all instances of the class.
EXAMPLE PROGRAM:-
Method references provide a cleaner and more concise way of using lambda expressions.
EXAMPLE PROGRAM:-
import java.util.Arrays;
import java.util.List;
public class Main {
public static void printName(String name) {
System.out.println(name);
}
public static void main(String[] args) {
List<String> names = Arrays.asList("John", "Jane", "Alice", "Bob");
Inner classes are classes that are nested within another class. They are useful for logically
grouping classes that should only be used in the context of the enclosing class.
EXAMPLE PROGRAM:-
The Singleton pattern ensures that a class has only one instance and provides a global point of
access to it.
EXAMPLE PROGRAM:-
The framework provides a set of classes and interfaces for storing and manipulating data,
such as Lists, Sets, Maps, and Queues.
It helps with efficient data manipulation and iteration, with the root interfaces being
Collection (for collections of elements) and Map (for key-value pairs).
CORE INTERFACES
Collection Interface
The Collection interface is the root for all other collection types. It provides basic functionality
for adding, removing, and checking elements.
Key Methods:
EXAMPLE PROGRAM:
import java.util.ArrayList;
import java.util.Collection;
public class CollectionExample {
public static void main(String[] args) {
Collection<String> collection = new ArrayList<>();
collection.add("Apple");
collection.add("Banana");
collection.add("Cherry");
System.out.println("Collection: " + collection); // Output: [Apple, Banana, Cherry]
collection.remove("Banana");
System.out.println("After Removal: " + collection); // Output: [Apple, Cherry]
System.out.println("Contains 'Apple': " + collection.contains("Apple")); // Output: true
System.out.println("Size: " + collection.size()); // Output: 2
collection.clear();
System.out.println("Is Empty: " + collection.isEmpty()); // Output: true
}
}
LIST INTERFACE
The List interface extends Collection and allows ordered collections with duplicate elements.
Elements can be accessed via an index.
Implementations:
Key Methods:
EXAMPLE PROGRAM:
import java.util.ArrayList;
SET INTERFACE
The Set interface represents a collection of unique elements. It does not allow duplicates.
Implementations:
Key Methods:
1. boolean add(E e): Adds the specified element if not already present.
2. boolean remove(Object o): Removes the specified element.
3. boolean contains(Object o): Checks if the element is present.
EXAMPLE PROGRAM:
import java.util.HashSet;
public class SetExample {
public static void main(String[] args) {
HashSet<Integer> set = new HashSet<>();
set.add(10);
set.add(20);
set.add(30);
set.add(10); // Duplicate element
System.out.println("Set: " + set); // Output: [10, 20, 30]
set.remove(20);
System.out.println("After Removal: " + set); // Output: [10, 30]
System.out.println("Contains 30: " + set.contains(30)); // Output: true
}}
QUEUE INTERFACE
The Queue interface represents a collection designed for holding elements prior to processing. It
usually follows FIFO order.
Implementations:
Key Methods:
EXAMPLE PROGRAM:
import java.util.LinkedList;
import java.util.Queue;
public class QueueExample {
public static void main(String[] args) {
Queue<String> queue = new LinkedList<>();
queue.add("A");
queue.add("B");
queue.add("C");
System.out.println("Queue: " + queue); // Output: [A, B, C]
System.out.println("Head: " + queue.peek()); // Output: A
queue.poll(); // Removes A
System.out.println("After Poll: " + queue); // Output: [B, C]
}}
MAP INTERFACE
The Map interface maps keys to values. Each key must be unique.
Implementations:
Key Methods:
1. V put(K key, V value): Associates the specified value with the key.
2. V get(Object key): Retrieves the value associated with the key.
3. boolean containsKey(Object key): Checks if the map contains the key.
4. boolean containsValue(Object value): Checks if the map contains the value.
5. V remove(Object key): Removes the key-value pair.
EXAMPLE PROGRAM:
import java.util.HashMap;
public class MapExample {
public static void main(String[] args) {
HashMap<Integer, String> map = new HashMap<>();
map.put(1, "One");
map.put(2, "Two");
map.put(3, "Three");
System.out.println("Map: " + map); // Output: {1=One, 2=Two, 3=Three}
System.out.println("Value for key 2: " + map.get(2)); // Output: Two
map.remove(1);
System.out.println("After Removal: " + map); // Output: {2=Two, 3=Three}
}}
SPECIALIZED METHODS IN COLLECTION IMPLEMENTATIONS
ARRAYLIST
ArrayList is a resizable array implementation of the List interface. It provides random access to
elements with dynamic growth.
Key Methods:
EXAMPLE PROGRAM:
import java.util.ArrayList;
public class ArrayListExample {
public static void main(String[] args) {
ArrayList<String> fruits = new ArrayList<>();
fruits.add("Apple");
fruits.add("Banana");
fruits.add("Cherry");
System.out.println("Fruits: " + fruits); // Output: [Apple, Banana, Cherry]
fruits.add(1, "Blueberry");
System.out.println("After Adding: " + fruits); // Output: [Apple, Blueberry, Banana, Cherry]
fruits.remove("Banana");
System.out.println("After Removal: " + fruits); // Output: [Apple, Blueberry, Cherry]
}}
LINKEDLIST
LinkedList implements both the List and Deque interfaces. It is a doubly-linked list, suitable for
frequent insertions and deletions.
EXAMPLE PROGRAM:
import java.util.LinkedList;
public class LinkedListExample {
public static void main(String[] args) {
LinkedList<String> animals = new LinkedList<>();
animals.add("Dog");
animals.add("Cat");
animals.addFirst("Elephant");
animals.addLast("Lion");
System.out.println("Animals: " + animals); // Output: [Elephant, Dog, Cat, Lion]
System.out.println("First Animal: " + animals.getFirst()); // Output: Elephant
System.out.println("Last Animal: " + animals.getLast()); // Output: Lion
animals.removeFirst();
System.out.println("After Removing First: " + animals); // Output: [Dog, Cat, Lion]
}}
HASHSET
HashSet implements the Set interface. It uses a hash table for storage, ensuring unique and
unordered elements.
EXAMPLE PROGRAM:
import java.util.HashSet;
public class HashSetExample {
public static void main(String[] args) {
HashSet<Integer> numbers = new HashSet<>();
numbers.add(10);
numbers.add(20);
numbers.add(30);
System.out.println("HashSet: " + numbers); // Output: [10, 20, 30]
numbers.add(20); // Duplicate element, no effect
System.out.println("After Adding Duplicate: " + numbers); // Output: [10, 20, 30]
numbers.remove(10);
System.out.println("After Removal: " + numbers); // Output: [20, 30]
}
}
TREESET
TreeSet implements the Set interface and maintains elements in sorted order. It is backed by a
TreeMap.
EXAMPLE PROGRAM:
import java.util.TreeSet;
public class TreeSetExample {
public static void main(String[] args) {
TreeSet<Integer> numbers = new TreeSet<>();
numbers.add(50);
numbers.add(20);
numbers.add(40);
numbers.add(10);
System.out.println("TreeSet: " + numbers); // Output: [10, 20, 40, 50]
System.out.println("First: " + numbers.first()); // Output: 10
System.out.println("Last: " + numbers.last()); // Output: 50
System.out.println("Ceiling of 25: " + numbers.ceiling(25)); // Output: 40
System.out.println("Floor of 25: " + numbers.floor(25)); // Output: 20
}
}
PRIORITYQUEUE
PriorityQueue implements the Queue interface, ordering elements according to their natural
order or a custom comparator.
Key Methods:
EXAMPLE PROGRAM:
import java.util.PriorityQueue;
public class PriorityQueueExample {
public static void main(String[] args) {
PriorityQueue<Integer> pq = new PriorityQueue<>();
pq.offer(30);
pq.offer(20);
pq.offer(10);
pq.poll(); // Removes 10
System.out.println("After Poll: " + pq); // Output: [20, 30]
}
}
ADVANCED FEATURES
EXAMPLE PROGRAM:
import java.util.*;
class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}}
public class ComparatorExample {
public static void main(String[] args) {
List<Person> people = new ArrayList<>();
people.add(new Person("Alice", 30));
people.add(new Person("Bob", 25));
people.add(new Person("Charlie", 35));
// Sort by age
people.sort(Comparator.comparingInt(p -> p.age));
for (Person p : people) {
System.out.println(p.name + " - " + p.age);
} // Output:
// Bob - 25
// Alice - 30
// Charlie - 35 }}
ITERATOR INTERFACE
Key Methods:
EXAMPLE PROGRAM:
import java.util.ArrayList;
import java.util.Iterator;
public class IteratorExample {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("C");
Iterator<String> it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
// Output: A B C
}
}
STREAMS
Key Methods:
EXAMPLE PROGRAM:
import java.util.Arrays;
import java.util.List;
public class StreamExample {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
numbers.stream()
.filter(n -> n % 2 == 0)
.forEach(System.out::println);
// Output: 2 4
}
}
The Map interface in Java is part of the Collections Framework and is used to store key-value
pairs. It does not inherit from the Collection interface but is a separate hierarchy.
Hierarchy of Map
1. Map Interface
o Represents a mapping between a key and a value.
2. HashMap
o Implements the Map interface using a hash table.
3. LinkedHashMap
o Extends HashMap and maintains insertion order.
4. TreeMap
o Implements NavigableMap and maintains elements in a sorted order.
5. WeakHashMap
o A map with keys eligible for garbage collection.
6. IdentityHashMap
o Uses reference equality instead of equals() for comparing keys.
7. ConcurrentHashMap
o A thread-safe implementation for high concurrency.
8. EnumMap
o A specialized map for keys of enum type.
General Methods
1. V put(K key, V value): Associates the specified value with the key.
2. V get(Object key): Returns the value associated with the key.
3. V remove(Object key): Removes the key-value pair for the key.
4. boolean containsKey(Object key): Checks if the key is present.
5. boolean containsValue(Object value): Checks if the value is present.
6. int size(): Returns the number of key-value mappings.
7. boolean isEmpty(): Checks if the map is empty.
8. void clear(): Removes all mappings.
9. Set<K> keySet(): Returns a set of all keys.
10. Collection<V> values(): Returns a collection of all values.
11. Set<Map.Entry<K, V>> entrySet(): Returns a set of all key-value mappings.
HASHMAP
EXAMPLE PROGRAM:
import java.util.HashMap;
public class HashMapExample {
public static void main(String[] args) {
HashMap<String, Integer> map = new HashMap<>();
map.put("A", 1);
map.put("B", 2);
map.put("C", 3);
System.out.println("HashMap: " + map); // Output: {A=1, B=2, C=3}
System.out.println("Value for key 'B': " + map.get("B")); // Output: 2
map.remove("A");
System.out.println("After Removing 'A': " + map); // Output: {B=2, C=3}
System.out.println("Contains Key 'B': " + map.containsKey("B")); // Output: true
System.out.println("Contains Value 3: " + map.containsValue(3)); // Output: true
}
}
LINKEDHASHMAP
EXAMPLE PROGRAM:
import java.util.LinkedHashMap;
public class LinkedHashMapExample {
public static void main(String[] args) {
LinkedHashMap<String, Integer> map = new LinkedHashMap<>();
map.put("Apple", 50);
map.put("Banana", 20);
map.put("Cherry", 30);
System.out.println("LinkedHashMap: " + map); // Output: {Apple=50, Banana=20,
Cherry=30}
map.put("Banana", 25); // Updates value for key 'Banana'
System.out.println("After Update: " + map); // Output: {Apple=50, Banana=25, Cherry=30}
}
}
TREEMAP
EXAMPLE PROGRAM:
import java.util.TreeMap;
public class TreeMapExample {
public static void main(String[] args) {
TreeMap<String, Integer> map = new TreeMap<>();
map.put("C", 3);
map.put("A", 1);
map.put("B", 2);
System.out.println("TreeMap: " + map); // Output: {A=1, B=2, C=3}
System.out.println("First Key: " + map.firstKey()); // Output: A
System.out.println("Last Key: " + map.lastKey()); // Output: C
}
}
WEAKHASHMAP
EXAMPLE PROGRAM:
import java.util.WeakHashMap;
public class WeakHashMapExample {
public static void main(String[] args) {
WeakHashMap<String, String> map = new WeakHashMap<>();
String key = new String("Key");
map.put(key, "Value");
System.out.println("Before GC: " + map); // Output: {Key=Value}
key = null;
System.gc(); // Garbage collection
System.out.println("After GC: " + map); // Output: {}
}
}
IDENTITYHASHMAP
EXAMPLE PROGRAM:
import java.util.IdentityHashMap;
public class IdentityHashMapExample {
public static void main(String[] args) {
IdentityHashMap<String, String> map = new IdentityHashMap<>();
String key1 = new String("Key");
String key2 = new String("Key");
map.put(key1, "Value1");
map.put(key2, "Value2");
System.out.println("IdentityHashMap: " + map);
// Output: {Key=Value1, Key=Value2}
}}
CONCURRENTHASHMAP
EXAMPLE PROGRAM:
import java.util.concurrent.ConcurrentHashMap;
public class ConcurrentHashMapExample {
public static void main(String[] args) {
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
map.put("One", 1);
map.put("Two", 2);
map.forEach((key, value) -> System.out.println(key + ": " + value));
// Output: One: 1
// Two: 2
}}
ENUMMAP
EXAMPLE PROGRAM:
import java.util.EnumMap;
enum Days {
MONDAY, TUESDAY, WEDNESDAY
}
public class EnumMapExample {
public static void main(String[] args) {
EnumMap<Days, String> map = new EnumMap<>(Days.class);
map.put(Days.MONDAY, "Work");
map.put(Days.TUESDAY, "Gym");
System.out.println("EnumMap: " + map); // Output: {MONDAY=Work,
TUESDAY=Gym}
}
}
ENTRY INTERFACE
EXAMPLE PROGRAM:
import java.util.HashMap;
import java.util.Map;
public class MapEntryExample {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<>();
map.put("A", 1);
map.put("B", 2);
for (Map.Entry<String, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
// Output: A: 1
// B: 2
}
}
COLLECTIONS :
The Collection interface in Java provides a variety of methods to manipulate and interact with
collections. Below is a summary of the most commonly used methods in the Collection interface,
along with a brief explanation of each:
1. Adding Elements
2. Removing Elements
remove(Object o): Removes the specified element from the collection if it exists.
o Example: list.remove("Apple");
removeAll(Collection<?> c): Removes all elements in the collection that are also
contained in the specified collection.
o Example: list.removeAll(anotherList);
retainAll(Collection<?> c): Retains only the elements in the collection that are contained
in the specified collection.
o Example: list.retainAll(anotherList);
clear(): Removes all elements from the collection.
o Example: list.clear();
3. Checking Properties
4. Iteration
java
Copy code
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
forEach(Consumer<? super E> action): Performs the given action for each element of the
collection.
o Example: list.forEach(System.out::println);
MULTITHREADING IN JAVA
1. Thread in Java
A thread in Java represents a single execution path within a program. The Java programming
language allows multiple threads to run concurrently, making it ideal for performing multiple
tasks at once. Each thread operates independently, but they share the same memory space (heap),
which allows them to communicate more easily than processes.
Java threads are lightweight, as they are managed by the Java Virtual Machine (JVM) and can be
executed in parallel by utilizing multiple CPU cores. Java provides two main ways to create
threads:
Extending the Thread class: A class extends Thread and overrides the run()
method.
Implementing the Runnable interface: A class implements Runnable and
provides the implementation of the run() method.
Java threads run concurrently, but not necessarily in parallel unless you have multiple
processors. The JVM determines the scheduling of threads, which makes Java an excellent
choice for concurrent applications.
The thread life cycle in Java defines the sequence of states that a thread goes through during its
existence. The states include:
1. New (Born):
o A thread is in the "New" state right after it is created, but before the start() method
is called.
o In this state, no CPU resources are allocated yet.
2. Runnable:
o After the thread is started (via the start() method), it enters the "Runnable" state.
o The thread can run at any point in time but is not guaranteed immediate
execution. It waits for the JVM to allocate CPU resources.
o The thread remains in the runnable state until it gets CPU time for execution.
3. Blocked:
o A thread enters the "Blocked" state when it cannot proceed because another
thread is holding a lock on a shared resource.
o This typically occurs when one thread is waiting to enter a synchronized block
while another thread is already inside it.
4. Waiting:
o A thread enters the "Waiting" state when it is waiting for another thread to
perform a particular action.
o This could occur when a thread calls methods like wait(), sleep(), or join().
5. Terminated (Dead):
o The thread enters the "Terminated" state when its run() method completes or it is
explicitly terminated.
o A dead thread cannot be restarted.
3. Thread Priority
Thread priority in Java allows you to influence the order in which threads are executed. The
JVM typically uses thread priority values to prioritize the execution of threads.
The JVM scheduler uses these priorities to allocate CPU time to threads, but it is not guaranteed
that higher-priority threads will always be executed before lower-priority ones. This depends on
the underlying OS's thread scheduling algorithm.
Time-sensitive tasks: High-priority threads are useful for tasks that need to be
executed without delay (e.g., real-time data processing).
Background tasks: Low-priority threads are suitable for non-critical tasks that can
wait for resources.
4. Thread Class
The Thread class in Java is a built-in class that allows you to create and manage threads. Some
important methods in the Thread class include:
start(): This method is used to begin the execution of a thread. Once start() is called, the
thread enters the "Runnable" state.
run(): This method contains the logic to be executed by the thread. It is called
automatically when a thread starts.
sleep(long millis): Pauses the thread for the specified number of milliseconds.
setPriority(int priority): This method sets the priority of a thread. The priority is a
value between Thread.MIN_PRIORITY and Thread.MAX_PRIORITY.
join(): Makes the current thread wait until the thread it is called on has completed its
execution.
5. Runnable Interface
The Runnable interface is a functional interface that represents a task to be executed by a thread.
It provides a more flexible way of creating threads compared to extending the Thread class.
Instead of creating a subclass of Thread, you implement the Runnable interface and provide the
implementation of the run() method. This approach allows your class to extend other classes as
well, which would not be possible if it extended Thread.
Benefits:
It provides better flexibility since a class can implement Runnable and still extend
another class.
It decouples the task from the thread management logic, making the task more reusable.
6. Synchronized Methods
By marking a method with the synchronized keyword, Java ensures that only one thread can
execute it at a time for each instance of the class.
public synchronized void increment() {
counter++;
}
Data Integrity: When multiple threads are modifying the same resource (e.g.,
counters, lists).
Critical Sections: When you want to ensure that a piece of code that modifies shared
resources is executed by only one thread at a time.
7. Daemon Threads
A daemon thread is a special type of thread that runs in the background and is used to
perform tasks such as garbage collection, event handling, or system monitoring.
Daemon threads do not prevent the JVM from shutting down when all user threads (non-daemon
threads) are completed.
Creating Daemon Threads: Daemon threads are created by calling setDaemon(true) before
starting the thread.
8. Thread Pool
A thread pool is a collection of threads that are used to execute tasks. Instead of creating new
threads for each task, you use a pool of pre-existing threads to execute multiple tasks. This
improves the efficiency of your program by minimizing the overhead associated with creating
and destroying threads.
The ExecutorService framework provides thread pool management capabilities. Common thread
pool types are:
9. Thread Group
A Thread Group is a way to organize and manage related threads. A thread group allows you
to perform collective actions on all threads within that group, such as changing their priorities or
interrupting them.
You can use thread groups to manage threads with similar behavior or to separate threads
logically for different purposes.
When you want to apply an operation on multiple threads (e.g., interrupting a group of
threads simultaneously).
When you want to organize threads in a way that reflects their purpose or lifecycle.
EXAMPLE PROGRAM
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
class ShoppingCart {
this.customerName = customerName;
this.itemPrices = itemPrices;
totalBill += price;
return customerName;
return totalBill;
}}
this.cart = cart;
@Override
cart.calculateTotalBill();
}}
ShoppingCart[] carts = {
};
ExecutorService executorService = Executors.newFixedThreadPool(3);
executorService.submit(new CustomerCheckout(cart));
executorService.shutdown();
}}
OUTPUT:-
SQL (Structured Query Language) is the standard programming language used to manage and
manipulate relational databases. It allows for querying, inserting, updating, and deleting data.
SQL commands are used for defining, managing, and querying data in a relational database.
WHAT IS A DATABASE?
A database is a structured collection of data. It is designed to store, manage, and retrieve large
MySQL is an open-source, relational database management system that uses SQL for managing
data. It is widely used in web applications due to its performance, reliability, and ease of use. It
supports a variety of data types and is capable of handling large volumes of data.
CONSTRAINTS IN SQL
Constraints are used to ensure data integrity and consistency in a relational database. The most
common types of constraints are:
SQL OPERATORS
SQL operators allow you to perform operations on data within queries. Here are some common
operators:
1. Arithmetic Operators:
o +, -, *, /, % (addition, subtraction, multiplication, division, modulus).
2. Comparison Operators:
o =, !=, >, <, >=, <= (equal, not equal, greater than, less than, etc.).
3. Logical Operators:
o AND, OR, NOT.
4. BETWEEN: Filters values within a given range.
5. IN: Checks if a value matches any value in a list.
6. LIKE: Allows pattern matching.
7. IS NULL: Checks for NULL values.
Output:
new_salary
55000.00
62000.00
72000.00
Output:
name salary
John 60000
name salary
Sarah 75000
Output:
name salary
John 60000
This query retrieves employees who earn more than 50,000 and work in department 101.
SELECT name
FROM employees
WHERE name LIKE 'J%';
Output:
name
John
James
This query retrieves employees whose names start with the letter 'J'.
A BLOB (Binary Large Object) is used to store large binary data such as images, videos, or
audio files. In MySQL, BLOB types allow you to store large amounts of binary data.
Output:
The image is stored in the image_data column of the table. It is now saved as a BLOB in the
database.
Output:
This query fetches the name of the image and the binary data (image) stored in the image_data
column.
A view in SQL is a virtual table created by a query that selects data from one or more tables.
Views do not store data physically but provide a dynamic way of presenting data based on
specific queries.
Creating a View
Output:
Using a View
Output:
A trigger is a set of SQL statements that are automatically executed (or "fired") when a
specified event occurs on a table or view. It can be set to run before or after events such as
INSERT, UPDATE, or DELETE.
Output:
Before a new employee's salary is inserted, it will be rounded to two decimal places.
Output:
After an employee's salary is updated, the change is logged in the employee_audit table.
A Foreign Key (FK) is a column or a set of columns in one table that refers to the primary
key of another table. The foreign key establishes a relationship between two tables and ensures
referential integrity. This means that the data in the foreign key column must correspond to
values in the primary key column of the referenced table, or it can be null.
Consider two tables: orders and customers. We want to establish a relationship between these
two tables using the customer_id column in the orders table, which refers to the id column in the
customers table.
Output:
The orders table now references the customers table using the customer_id column. When
inserting data into the orders table, the value in customer_id must exist in the customers table,
ensuring referential integrity.
WHAT IS A JOIN IN SQL?A Join is used to combine rows from two or more tables
based on a related column between them. There are several types of joins, including:
INNER JOIN: Returns records that have matching values in both tables.
LEFT JOIN (or LEFT OUTER JOIN): Returns all records from the left table and
matched records from the right table, or NULL if there is no match.
RIGHT JOIN (or RIGHT OUTER JOIN): Returns all records from the right table and
matched records from the left table, or NULL if there is no match.
FULL JOIN (or FULL OUTER JOIN): Returns records when there is a match in
either left or right table.
CROSS JOIN: Returns the Cartesian product of both tables (every combination of
rows from both tables).
Output:
This query retrieves the customer name, order ID, and order amount for all customers who have
placed an order, using the INNER JOIN between customers and orders.
Output:
This query retrieves all customers, including those who have not placed an order. If no matching
records are found in the orders table, the result is NULL.
An Index is a database object that improves the speed of data retrieval operations on a table at
the cost of additional space and maintenance time. Indexes are often created on columns that are
frequently used in WHERE, JOIN, or ORDER BY clauses.
Creating an Index
Data integrity refers to the accuracy, consistency, and reliability of data stored in a database.
It ensures that data remains accurate and consistent throughout its lifecycle. The primary
mechanisms for maintaining data integrity are constraints, such as NOT NULL, UNIQUE,
PRIMARY KEY, and FOREIGN KEY.
Output:
The table ensures that:
A subquery is a query nested inside another query. Subqueries are used to retrieve
intermediate results that are then used in the main query. A subquery can be used in the
SELECT, INSERT, UPDATE, or DELETE statements.
Example of a Subquery
SELECT name
FROM employees
WHERE department_id = (
SELECT department_id
FROM departments
WHERE dept_name = 'HR'
);
Output:
name
John
Mike
This query retrieves the names of employees who work in the "HR" department. The subquery
fetches the department_id for "HR", and the main query uses it to filter employees.
WHAT IS A STORED PROCEDURE IN SQL?
A Stored Procedure is a set of SQL statements that are stored in the database and can be
executed as a single unit. Stored procedures are used to encapsulate logic, improve performance,
and reduce redundancy.
Output:
The stored procedure GetEmployeeDetails takes an employee ID as an input parameter and
retrieves the name and salary of the employee with that ID.
CALL GetEmployeeDetails(1);
Output:
name salary
John 60000
This query executes the GetEmployeeDetails procedure and returns the details of the employee
with emp_id = 1.
A Transaction is a set of SQL operations that are executed as a single unit. A transaction
ensures that all operations within it are completed successfully before committing the changes. If
any operation fails, the transaction can be rolled back to maintain consistency.
Transaction Commands
Example of a Transaction
START TRANSACTION;
UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;
UPDATE accounts SET balance = balance + 100 WHERE account_id = 2;
COMMIT;
Output:
This transaction transfers 100 units from one account to another. If both updates succeed, the
changes are committed. If any update fails, a ROLLBACK can be issued to undo the changes.
Output:
This command creates a backup of the database_name and saves it in the backup. file.
Output:
This command restores the database from the backup. file.
A Trigger is a special type of stored procedure that automatically runs when certain events
occur on a particular table or view. Triggers are commonly used to enforce data integrity,
automate system functions, and maintain audit logs. Triggers can be set to execute after
(AFTER), before (BEFORE), or instead of (INSTEAD OF) a specified database operation, such
as INSERT, UPDATE, or DELETE.
Creating a Trigger
Consider a scenario where you want to automatically update an audit table whenever a record is
inserted into the employees table. Here's an example of creating a trigger for this purpose:
Output:
The employee_insert_trigger trigger automatically inserts a record into the audit_log table every
time a new employee record is inserted into the employees table. The log includes the action
(INSERT), table name, and timestamp of the operation.
A View is a virtual table that is derived from one or more base tables. Views simplify complex
queries, provide an abstraction layer, and can be used to enhance security by exposing only
specific columns or rows from underlying tables. Views do not store data themselves but rather
store the SQL query that retrieves the data.
Creating a View
Here’s an example of creating a view that provides a summary of employee salaries by
department:
Output:
The department_salary_summary view provides the total salary of employees for each
department. To retrieve the data, you can query the view as you would a regular table:
Result:
department_id total_salary
1 120000
2 85000
Aggregate functions perform a calculation on a set of values and return a single value. Common
aggregate functions include:
Output:
These queries calculate the total number of employees, average salary, and highest salary in the
employees table.
A BLOB (Binary Large Object) is a data type used to store large binary data such as images,
audio, and video. BLOBs can store up to several gigabytes of data, depending on the database
system.
To store a BLOB in MySQL, you can use the BLOB data type for the column, and for inserting
an image, you would typically use a prepared statement to handle the binary data.
Output:
The image is stored in the image column of the product_images table. To retrieve the image, you
can query the table and return the BLOB data.
In MySQL, the REGEXP operator allows you to search for patterns in string columns.
Output:
This query retrieves all employees whose names start with the letter "A."
3. Correlated Subquery: A subquery that references columns from the outer query.
4. Non-correlated Subquery: A subquery that does not reference columns from the
outer query.
A single-row subquery returns a single value. For example, to retrieve employees whose salary is
higher than the average salary in the company:
Output:
This query returns all employees whose salary exceeds the average salary of all employees in the
company.
A multi-row subquery returns multiple values. For example, you can use a multi-row subquery to
get employees who work in departments that have more than 10 employees:
SELECT * FROM employees
WHERE department_id IN (SELECT department_id FROM employees GROUP BY
department_id HAVING COUNT(*) > 10);
Output:
This query returns employees who belong to departments with more than 10 employees.
A correlated subquery refers to columns from the outer query. For instance, to find employees
who earn more than the average salary in their respective department:
Output:
This query returns employees whose salary is greater than the average salary of their department.
An index is a database object that speeds up the retrieval of rows from a table. Indexes are
particularly useful when dealing with large datasets as they reduce the amount of data that must
be scanned during a query. Indexes are created on one or more columns of a table.
Creating an Index
Here’s an example of creating an index on the employee_id column in the employees table:
Types of Indexes
1. Unique Index: Ensures that all values in the indexed column are unique.
To improve the performance of queries filtering on both first_name and last_name columns, you
can create a composite index:
Output:
The composite index idx_name will speed up queries that filter by both first_name and
last_name.
1. Atomicity: Ensures that a transaction is treated as a single unit, which either succeeds
or fails as a whole.
2. Consistency: Ensures that the database remains in a consistent state before and after
the transaction.
3. Isolation: Ensures that the operations of one transaction are isolated from those of other
concurrent transactions.
4. Durability: Ensures that the changes made by a committed transaction are permanent,
even in the event of a system crash.
BEGIN TRANSACTION;
UPDATE employees
SET salary = salary + 5000
WHERE department_id = 3;
UPDATE departments
SET budget = budget - 5000
WHERE department_id = 3;
COMMIT;
Output:
This series of commands starts a transaction, updates the salaries of employees in department 3,
adjusts the department's budget, and commits the changes to the database.
A stored procedure is a precompiled collection of one or more SQL statements stored in the
database. Stored procedures are used to encapsulate business logic, perform operations like
inserting, updating, and deleting data, and handle complex queries.
A function in SQL is similar to a stored procedure but is designed to return a value. Functions
can be used to perform operations like calculations, string manipulations, or aggregation on data.
Creating a Function
Here’s an example of creating a function that calculates the annual salary based on the monthly
salary:
Output:
This function takes a monthly_salary as input and returns the annual salary by multiplying the
monthly salary by 12.
Output:
This query will return the names of employees along with their annual salaries.
TYPES OF JOINS
1. INNER JOIN: Returns records that have matching values in both tables.
2. LEFT JOIN (or LEFT OUTER JOIN): Returns all records from the left table,
and the matched records from the right table. If there is no match, NULL values are
returned for the right table's columns.
3. RIGHT JOIN (or RIGHT OUTER JOIN): Similar to the LEFT JOIN, but it
returns all records from the right table and the matching records from the left table.
4. FULL JOIN (or FULL OUTER JOIN): Returns all records when there is a
match in either left or right table. Rows without matches will have NULL values in
columns from the table with no match.
5. SELF JOIN: Joins a table with itse
Suppose you have two tables: employees and departments. You want to get a list of all
employees along with the department names they belong to. This can be achieved using an
INNER JOIN:
SELECT employees.name, employees.salary, departments.department_name
FROM employees
INNER JOIN departments
ON employees.department_id = departments.department_id;
Output:
This query returns a list of employee names, their salaries, and the corresponding department
names, but only for employees who are assigned to a department.
If you want to include all employees, even those who don't belong to any department, you can
use a LEFT JOIN:
Output:
This query will return a list of all employees, their salaries, and department names. Employees
who are not assigned to a department will show NULL for the department_name.
Similarly, a RIGHT JOIN ensures that all records from the right table are included, even if there
is no matching record in the left table:
Output:
This query returns a list of all departments and employees in those departments. Departments
with no employees will show NULL for employee data.
A FULL JOIN returns all rows when there is a match in one of the tables:
Output:
This query returns a list of all employees and departments, including employees without
departments and departments without employees.
A Self Join is used to join a table with itself. For instance, if you want to list managers and the
employees they manage, assuming that the employees table has a manager_id column:
Output:
This query lists employees along with their respective managers. Employees without managers
will show NULL for the manager_name.
SQL allows you to group rows and apply aggregate functions to summarize data. This is
typically done using the GROUP BY clause along with aggregate functions such as COUNT,
SUM, AVG, MAX, and MIN.
For example, if you want to count the number of employees in each department:
Output:
This query returns the number of employees in each department.
If you want to find the total salary and average salary of employees in each department:
Output:
This query returns the total and average salary of employees in each department.
HAVING CLAUSE
The HAVING clause is used to filter the results of aggregate functions, similar to how WHERE
filters individual rows. It is applied after the GROUP BY clause.
For instance, to find departments with an average salary greater than 50,000:
Output:
This query returns departments with an average salary greater than 50,000.
SQL CONSTRAINTS
Constraints are rules applied to the columns of a table to ensure data integrity and consistency.
There are several types of constraints in SQL.
Types of Constraints
3. PRIMARY KEY: Uniquely identifies each record in a table and automatically applies
the NOT NULL and UNIQUE constraints.
4. FOREIGN KEY: Ensures the integrity of data between two tables by linking a
column in one table to a primary key in another.
5. CHECK: Ensures that the values in a column satisfy a specific condition.
Output:
This query creates an employees table with employee_id and department_id as mandatory (NOT
NULL), and name as unique.
Output:
This creates a departments table with a primary key and an employees table with a foreign key
constraint linking department_id to departments.department_id.
SQL OPERATORS
SQL operators allow you to perform operations on values in a query. Some commonly used SQL
operators include:
Output:
This query returns employees who have a salary greater than 50,000.
Output:
This query returns employees who belong to departments 1, 2, or 3.
Output:
This query returns employees whose name starts with the letter 'J'.
Stored Procedures
A Stored Procedure is a set of SQL statements that are stored in the database and executed
as a single unit. They can take parameters, execute multiple SQL statements, and even return
results.
Here's an example of creating a stored procedure that calculates the total salary of employees in a
given department:
DELIMITER //
DELIMITER ;
Explanation:
DELIMITER //: Changes the delimiter temporarily so that semicolons can be used within
the procedure.
IN dept_id INT: This defines an input parameter dept_id of type INT.
SUM(salary) AS total_salary: This aggregates the salaries of employees in the specified
department.
CALLING THE STORED PROCEDURE
To call the stored procedure and get the total salary for department 1:
CALL CalculateTotalSalary(1);
Output:
The result will show the total salary for all employees in department 1.
Functions
A Function in SQL is similar to a stored procedure but returns a single value. Functions are
commonly used for computations like calculating totals, averages, or transforming data.
CREATING A FUNCTION
Here's an example of creating a function that returns the average salary of employees in a
specific department:
DELIMITER //
CREATE FUNCTION GetAverageSalary(dept_id INT)
RETURNS DECIMAL(10,2)
BEGIN
DECLARE avg_salary DECIMAL(10,2);
SELECT AVG(salary) INTO avg_salary
FROM employees
WHERE department_id = dept_id;
RETURN avg_salary;
END //
DELIMITER ;
Explanation:
RETURNS DECIMAL(10,2): Specifies the return type of the function (in this case, a
decimal number with 2 decimal places).
SELECT AVG(salary) INTO avg_salary: Retrieves the average salary into the variable
avg_salary.
RETURN avg_salary: Returns the calculated average salary.
To call the function and get the average salary for department 2:
SELECT GetAverageSalary(2);
Output:
The result will return the average salary of employees in department 2.
Triggers
A Trigger is a set of SQL statements that are automatically executed in response to certain
events on a particular table or view. Triggers are useful for enforcing business rules, data
validation, and maintaining data integrity.
Creating a Trigger
Here's an example of a trigger that automatically updates an employee’s last modified date
whenever their record is updated:
DELIMITER //
CREATE TRIGGER update_employee_timestamp
BEFORE UPDATE ON employees
FOR EACH ROW
BEGIN
SET NEW.last_modified = NOW();
END //
DELIMITER ;
Explanation:
BEFORE UPDATE: Specifies that the trigger will fire before an update operation.
FOR EACH ROW: Ensures the trigger is applied to each affected row.
SET NEW.last_modified = NOW(): Updates the last_modified column with the current
date and time.
TRIGGER EXECUTION
This trigger will automatically execute whenever an employee record is updated, ensuring that
the last_modified field is always up-to-date.
Views
A View is a virtual table based on the result of a query. Views can simplify complex queries,
enhance security by restricting access to sensitive data, and provide a consistent interface to
users.
Creating a View
Here's an example of creating a view that displays employee names along with their department
names:
Explanation:
To query the view and get a list of all employees and their departments:
Output:
This query returns the employee names, their salaries, and department names as specified in the
view.
INDEXES
Indexes are used to speed up the retrieval of data from a table. When you create an index on a
column, the database creates an internal structure that allows for faster searches.
Creating an Index
Here's an example of creating an index on the department_id column in the employees table:
Understanding the available data types in SQL is crucial for designing efficient and robust
databases. Here’s an overview of common data types:
5. DECIMAL(p,s): Used to store precise numeric values, where p is the total number of
digits and s is the number of digits to the right of the decimal point.
6. BLOB: Used to store binary data, such as images or files.
The BLOB data type (Binary Large Object) is used to store large amounts of binary data, such
as images, files, and other media. Here’s an example of inserting and retrieving a BLOB:
Inserting a BLOB
Explanation:
LOAD_FILE('/path/to/image.jpg'): Loads the image file from the specified path into the
product_image column.
Retrieving a BLOB
SELECT product_image
FROM products
WHERE product_id = 1;
Output:
This query retrieves the binary image data for the product with product_id = 1.
What is HTML?
HTML stands for Hypertext Markup Language. It is the standard language used to
create and structure content on the web. It tells the web browser how to display text, links,
images, and other forms of multimedia on a webpage. HTML sets up the basic structure of a
website, and then CSS and JavaScript add style and interactivity to make it look and function
better.
Features of HTML:
History of HTML:
What is CSS?
CSS (Cascading Style Sheets) is a language designed to simplify the process of making web
pages presentable. It allows you to apply styles to HTML documents, describing how a
webpage should look by prescribing colors, fonts, spacing, and positioning. CSS provides
developers and designers with powerful control over the presentation of HTML elements
Separation of Content and Style: CSS allows developers to separate the content (HTML)
from its visual representation, making maintenance easier and more efficient.
Styling Rules: CSS uses rules to apply styles to elements. Each rule consists of a selector
and a declaration block.
Cascading Nature: The "Cascading" in CSS means that styles can fall (or cascade) from
one style sheet to another, and multiple style rules can be combined.
Responsive Design: CSS provides tools for creating responsive designs that adapt to
different screen sizes and devices.
Animation and Interaction: CSS supports animations and transitions, enhancing user
interaction and visual appeal.
History of CSS:
HTML Structure:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<h1>Welcome to My Webpage</h1>
</body>
</html>
CSS Syntax:
selector {
property: value;
}
Example CSS:
body {
h1 {
h2 {
p{
/* Links style */
a{
a:hover {
1.Inline CSS:
What It Is: Apply styles directly to individual HTML elements using the style
attribute.
Example:
Explanation: The styles are added directly to the h1 and p tags using the style attribute.
2. Internal CSS:
What It Is: Add styles in the <style> tag inside the <head> section of the same HTML
page.
Example:
<!DOCTYPE html>
<html>
<head>
<title>My eBook</title>
<style>
body {
background-color: #f0f0f0;
h1 {
color: green;
text-align: center;
p{
font-size: 18px;
color: #333;
</style>
</head>
<body>
<h1>Welcome to My eBook</h1>
</body>
</html>
Explanation: The styles are placed in the <style> section at the top of the HTML document
and apply to all content in the body.
External CSS:
What It Is: Use a separate CSS file to style the HTML document. This method is the
best for large eBooks with multiple pages
Steps:
<!DOCTYPE html>
<html>
<head>
<title>My eBook</title>
<link rel="stylesheet" href="ebook-style.css">
</head>
<body>
<h1>Welcome to My eBook</h1>
<p>This is the first chapter of my eBook.</p>
</body>
</html>
Explanation: The <link> tag in the <head> section links the external ebook-style.css file
to the HTML page, applying the styles defined in that file
3.HTML ELEMENTS:
1. <html>
What It Does: This is the root element that wraps all your HTML content. Every
HTML document starts with this tag.
Example:
<html>
<!-- All content goes here -->
</html>
2. <head>
What It Does: Contains metadata about your eBook, such as the title, links to
stylesheets, and scripts.
Example:
<head>
<title>My eBook</title>
</head>
3. <title>
What It Does: Sets the title that appears on the browser tab when the eBook is opened.
Example:
<title>Chapter 1: Introduction</title>
4. <body>
What It Does: Contains the visible content of the eBook that readers see, such as text,
images, and links.
Example:
<body>
<h1>Welcome to My eBook</h1>
<p>This is the first paragraph.</p>
</body>
What It Does: Headings define titles and subheadings. <h1> is the main title, <h2> is
for section titles, and so on.
Example:
<h1>Welcome to My eBook</h1>
<h2>Chapter 1: Introduction</h2>
6. <p> (Paragraph)
What It Does: Used for regular text. Each <p> tag contains a paragraph of text.
Example:
7. <img> (Image)
What It Does: Adds an image to your eBook. You need to specify the image's source
using the src attribute.
Example:
What It Does: Creates clickable links. You use the href attribute to define the
destination URL.
Example:
What It Does: Creates a list of items without numbers. Each item inside the list is
defined by <li>.
Example:
<ul>
<li>Introduction</li>
<li>Chapter 1: Basics</li>
<li>Chapter 2: Advanced Topics</li>
</ul>
What It Does: Creates a list of items with numbers or letters. Each item is defined by
<li>.
Example:
<ol>
<li>Step 1: Open the eBook</li>
<li>Step 2: Read the first chapter</li>
<li>Step 3: Continue to the next chapter</li>
</ol>
11. <strong>
What It Does: Makes text bold and important, usually to emphasize a word or phrase.
Example:
12. <em>
What It Does: Makes text italic, usually used to emphasize a word or phrase.
Example:
13. <blockquote>
<blockquote>
"This is a quote from another book."
</blockquote>
<hr>
4.HTML STYLES:
What It Is: Inline CSS is when you apply styles directly to a specific HTML element
using the style attribute.
Usage: This method is best for quick and small changes.
Example:
o Explanation: Here, the style attribute is used to change the color and text
alignment of the heading (h1), and the font size and color of the paragraph (p).
What It Is: Internal CSS is used when you define styles in the <style> tag within the
<head> section of your HTML page.
Usage: This is good for styling a single page of the eBook.
Example:
<!DOCTYPE html>
<html>
<head>
<title>My eBook</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
}
h1 {
color: darkblue;
text-align: center;
}
p{
font-size: 16px;
color: #333;
}
</style>
</head>
<body>
<h1>Chapter 1: Introduction</h1>
<p>Welcome to the first chapter of my eBook!</p>
</body>
</html>
o Explanation: The <style> tag in the <head> section contains CSS rules for the
body, h1, and p elements. This style will apply to the entire page.
What It Is: External CSS is the best method for large eBooks. It allows you to store
styles in a separate CSS file and link that file to your HTML document.
Usage: Perfect for large eBooks with many chapters, ensuring consistent design across
all pages.
Steps:
body {
font-family: "Times New Roman", serif;
line-height: 1.8;
background-color: #fff;
}
h1 {
color: purple;
text-align: center;
}
p{
font-size: 18px;
color: #555;
}
<!DOCTYPE html>
<html>
<head>
<title>My eBook</title>
<link rel="stylesheet" type="text/css" href="ebook-style.css">
</head>
<body>
<h1>Welcome to My eBook</h1>
<p>This is the first chapter styled using external CSS.</p>
</body>
</html>
o Explanation: The <link> tag links the ebook-style.css file to the HTML
document, applying the styles defined in that file to the page.
5. HTML HEADING:
There are six levels of headings in HTML, from <h1> to <h6>. The <h1> tag is the most
important (largest), while the <h6> tag is the least important (smallest).
Example:
Explanation: The text inside each heading tag is displayed with different sizes and
importance. <h1> is used for the main title, <h2> for chapters, and so on for sections and
subsections.
6. HTML FORMATTING:
HTML offers several tags to format text. These tags help you bold, italicize, underline, and
strike-through text.
Bold Text:
Explanation: The <b> tag makes text bold for styling purposes, while <strong> has a
semantic meaning of importance, making it bold.
Italic Text:
Explanation: The <i> tag is for text that is styled as italic, and <em> is used for
emphasis, which also italicizes the text.
Underlined Text:
Strike-through Text:
In HTML, paragraphs and line breaks are essential for organizing text into readable chunks.
Paragraph:
Explanation: The <p> tag automatically separates paragraphs with space, making the
content easier to read.
Line Break:
The <br> tag is used to break the line without creating a new paragraph.
Explanation: The <br> tag forces the next content to appear on a new line without
starting a new paragraph.
HTML allows you to create both ordered and unordered lists, making your content structured
and easy to follow.
Use the <ul> (unordered list) and <li> (list item) tags to create a bulleted list.
<ul>
<li>Introduction to HTML</li>
<li>HTML Structure</li>
<li>HTML Tags and Attributes</li>
</ul>
Explanation: The <ul> tag creates a bulleted list, and each <li> tag defines a list item.
Use the <ol> (ordered list) and <li> tags to create a numbered list.
<ol>
<li>Chapter 1: Introduction</li>
<li>Chapter 2: Basics of HTML</li>
<li>Chapter 3: Advanced HTML Techniques</li>
</ol>
Explanation: The <ol> tag creates a numbered list, and each <li> tag defines a list
item.
4. Text Alignment
HTML allows you to align text to the left, right, center, or justify it.
By default, text is aligned to the left, but you can specify it using the align attribute or CSS.
Justify Text:
<p style="text-align: justify;">This text is justified, meaning it stretches to fit both the left and
right margins.</p>
5. Font Formatting
You can change the font style, size, and color of the text to make it more attractive.
<p style="font-family: Arial, sans-serif;">This text uses the Arial font family.</p>
The <blockquote> tag is used to display long quotes or cited text, often indented.
<blockquote>
<p>"HTML is the foundation of web development." - Web Development Guru</p>
</blockquote>
Explanation: The <blockquote> tag is used for quoting or citing text from other
sources.
Example:
Explanation: Here, both the <b> and <i> tags are used to apply bold and italic styles to
the text.
7. HTML LINKS:
href: Specifies the URL (web address) of the page or document you want to link to.
Link Text: The clickable text that appears to the reader.
Example:
Explanation: This link will take the reader to the "Example Website" when clicked.
2. Types of Links
Explanation: Clicking "Go to Chapter 1" will scroll the reader to the section with the
ID chapter1.
Explanation: This link opens the "about.html" page located in the same website or
project.
4. Adding a Tooltip
You can add a tooltip to your link using the title attribute. The tooltip appears when the reader
hovers over the link.
Explanation: When the reader hovers over the link, the tooltip "Click to visit Example
Website" appears.
5. Styling Links
You can style links using CSS to change their color, font, or hover effects.
Example:
Explanation: The link text will appear in blue and without an underline.
Explanation: The link text changes to red when the reader hovers over it and back to
blue when the hover ends.
To create a link that opens an email client, use mailto: in the href attribute.
<a href="mailto:[email protected]">Email Us</a>
Explanation: Clicking the link will open the default email client with the address
[email protected] ready to send an email.
To create a clickable phone number link, use tel: in the href attribute.
Explanation: Clicking the link will prompt a call to the number +1234567890 on
mobile devices.
8. Disabled Links
To create a link that isn’t clickable, omit the href attribute or set it to #.
8. HTML TABLES:
An HTML table is created using the <table> tag, with rows defined by <tr> (table row) and cells
by <td> (table data).
Example:
<table border="1">
<tr>
<td>Row 1, Cell 1</td>
<td>Row 1, Cell 2</td>
</tr>
<tr>
<td>Row 2, Cell 1</td>
<td>Row 2, Cell 2</td>
</tr>
</table>
Explanation: This table has two rows, each containing two cells. The border="1" adds
a border around the table.
You can use the <th> tag to create header cells, which are bold and centered by default.
Example:
<table border="1">
<tr>
<th>Header 1</th>
<th>Header 2</th>
</tr>
<tr>
<td>Data 1</td>
<td>Data 2</td>
</tr>
</table>
Explanation: The <th> tag is used for header cells, making the first row a header for
the table.
3. Adding a Caption to the Table
Example:
<table border="1">
<caption>Sample Data Table</caption>
<tr>
<th>Header 1</th>
<th>Header 2</th>
</tr>
<tr>
<td>Data 1</td>
<td>Data 2</td>
</tr>
</table>
Explanation: The caption appears above the table and gives it a title.
You can merge cells using the rowspan and colspan attributes.
<table border="1">
<tr>
<th colspan="2">Merged Header</th>
</tr>
<tr>
<td>Data 1</td>
<td>Data 2</td>
</tr>
</table>
<table border="1">
<tr>
<td rowspan="2">Merged Row</td>
<td>Data 1</td>
</tr>
<tr>
<td>Data 2</td>
</tr>
</table>
You can use CSS to style tables and make them look more attractive.
Example:
Explanation:
o The border-collapse: collapse; removes double borders.
o Background colors and text alignment are added for better presentation.
6. Example Table
The <input> tag is a self-closing tag and requires the type attribute to specify the kind of input.
a. Text Input
b. Password Input
c. Email Input
d. Number Input
<input type="number" placeholder="Enter a number" />
Explanation: Creates a field for numeric input with controls for increasing or
decreasing the value.
e. Radio Button
f. Checkbox
g. Submit Button
h. Reset Button
i. File Upload
You can use the <label> tag to associate a label with an input field, making it more user-friendly.
Example:
<label for="name">Name:</label>
<input type="text" id="name" placeholder="Enter your name" />
Explanation: The for attribute in the <label> matches the id of the input field.
Input elements are typically part of a form, which collects and submits data.
Example:
Explanation:
o The <form> tag groups input elements.
o The action attribute specifies where the form data is sent.
o The method attribute defines how the data is sent (post or get).
5. Placeholder Text
Example:
Explanation: The placeholder text disappears when the user starts typing.
6. Input Validation
You can add attributes to ensure users enter data in the correct format.
Example:
Disabled Input:
Read-Only Input:
Example:
<input type="text" style="border: 2px solid blue; padding: 10px; width: 200px;"
placeholder="Styled input" />
Explanation: This input field has a blue border, padding, and custom width.
The <img> tag is self-closing and requires the src (source) attribute to specify the image's
location.
Example:
Explanation: Displays an image of a flower. If the image cannot load, the text "A
beautiful flower" will appear.
Example:
Explanation: When the user hovers over the image, the title text "This is an open
book" appears.
3. Resizing an Image
You can control the size of the image using the width and height attributes.
Example:
Explanation: The image will display at 300 pixels wide and 200 pixels tall.
4. Responsive Images
To make images adjust automatically based on screen size, use the style attribute or CSS.
Example:
Explanation: The image will resize to fit the screen without distortion.
5. Linking an Image
<a href="https://example.com">
<img src="logo.jpg" alt="Website Logo" />
</a>
You can use images hosted on other websites by providing the full URL in the src attribute.
Example:
If you don’t have an image ready, you can use a placeholder image.
Example:
p{
color: blue;
}
b. Class Selector
.classname {
color: green;
}
Example: Styles all elements with the class "classname" to have green text.
c. ID Selector
#idname {
color: red;
}
Example: Styles the element with the ID "idname" to have red text.
d. Universal Selector
e. Attribute Selector
[attribute] {
color: purple;
}
[attribute="value"] {
color: orange;
}
Example:
o Styles all elements with a specified attribute to have purple text.
o Styles elements with a specific attribute value to have orange text.
2. Combining Selectors
a. Descendant Selector
div p {
color: blue;
}
Example: Styles all <p> elements inside a <div> with blue text.
b. Child Selector
div > p {
color: green;
}
Example: Styles only the direct <p> children of a <div> with green text.
h1 + p {
color: red;
}
Example: Styles the first <p> element that comes immediately after an <h1> with red
text.
h1 ~ p {
color: yellow;
}
Example: Styles all <p> elements that come after an <h1> with yellow text.
a. color
p{
color: blue;
}
b. font-size
h1 {
font-size: 24px;
}
c. font-family
body {
font-family: Arial, sans-serif;
}
d. text-align
Controls the alignment of text.
h2 {
text-align: center;
}
e. font-weight
p{
font-weight: bold;
}
a. background-color
div {
background-color: lightblue;
}
b. background-image
c. opacity
img {
opacity: 0.5;
}
div {
width: 200px;
height: 100px;
}
b. padding
p{
padding: 10px;
}
c. margin
h1 {
margin: 20px;
}
d. border
div {
border: 2px solid black;
}
a. display
span {
display: block;
}
Example: Makes the <span> behave like a block element.
b. position
div {
position: absolute;
top: 50px;
left: 100px;
}
Example: Places the <div> 50px from the top and 100px from the left.
c. z-index
img {
z-index: 10;
}
5. List Properties
a. list-style-type
ul {
list-style-type: square;
}
Example: Changes list bullets to squares.
b. list-style-image
ul {
list-style-image: url('bullet.png');
}
a. transition
button {
transition: background-color 0.3s ease;
}
b. animation
@keyframes example {
from { background-color: red; }
to { background-color: yellow; }
}
div {
animation: example 2s infinite;
}
Example: Animates a <div> to change its background color from red to yellow.
1. Absolute Units
Absolute units have a fixed size and do not change based on other elements.
2. Relative Units
Relative units adjust based on the size of their parent or other elements, making them flexible
and responsive.
Example:
p{
font-size: 1.5em;
margin-top: 10px;
width: 50%;
Responsive design ensures that web pages adapt and look great on all devices, including
desktops, tablets, and mobile phones. CSS provides tools like media queries to create
responsive layouts.
Media Queries
Media queries apply specific styles based on device characteristics such as screen width, height,
or orientation. This allows you to customize your page for different devices.
How It Works:
1. Default Styles: The base styles apply to all devices, unless overridden by a media
query.
o Background color: white.
o Font size: 16px.
2. For Large Screens:
o Devices with a screen width greater than 600px have a light blue background
and font size of 18px.
3. For Small Screens:
o Devices with a screen width less than or equal to 600px have a light green
background and font size of 14px.
1. Border Property
The border property is a shorthand for setting the width, style, and color of all four sides of an
element's border.
Syntax:
selector {
border: width style color;
}
Example:
div {
border: 2px solid black;
}
2. Border Width
The border-width property sets the thickness of the border. It accepts specific values (e.g., pixels)
or keywords like thin, medium, or thick.
Syntax:
selector {
border-width: value;
}
Example:
p{
border-width: 4px;
}
3. Border Style
The border-style property defines the appearance of the border. Common values include:
none: No border.
solid: A continuous line.
dotted: A series of dots.
dashed: A series of dashes.
double: Two solid lines.
groove: A 3D grooved border.
ridge: A 3D ridged border.
inset: A 3D inset border.
outset: A 3D outset border.
Syntax:
selector {
border-style: value;
}
Example:
h1 {
border-style: dashed;
}
Adds a dashed border around an <h1> element.
4. Border Color
The border-color property specifies the color of the border. You can use color names, HEX
codes, RGB, or RGBA values.
Syntax:
selector {
border-color: color;
}
Example:
h2 {
border-color: blue;
}
1. placeholder
Provides a hint or example text inside the input field to guide users on what to enter.
Example:
Displays "Enter your name" inside the input field until the user types something.
2. required
Marks the input field as mandatory. The form will not submit unless this field is filled.
Example:
Ensures the user enters a valid email address before submitting the form.
3. readonly
Makes the input field non-editable. Users can see the value but cannot modify it.
Example:
4. disabled
Disables the input field, preventing users from interacting with it.
Example:
The input field appears grayed out and cannot be clicked or edited.
5. maxlength
Example:
6. size
Specifies the width of the input field in terms of the number of characters it can display.
Example:
7. pattern
Defines a regular expression that the input value must match. Useful for validation.
Example:
8. autofocus
Automatically focuses on the input field when the web page loads.
Example:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Registration Form</title>
<style>
body {
background-color: #f2f2f2;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
.container {
background-color: white;
padding: 20px;
border-radius: 10px;
width: 300px;
.container h2 {
text-align: center;
margin-bottom: 20px;
.container label {
display: block;
margin-bottom: 5px;
.container input[type="text"],
.container input[type="email"],
.container input[type="password"] {
width: 100%;
padding: 10px;
margin-bottom: 10px;
border-radius: 5px;
.container input[type="submit"] {
width: 100%;
padding: 10px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
.container input[type="submit"]:hover {
background-color: #45a049;
.terms {
display: flex;
align-items: center;
margin-bottom: 10px;
.terms input[type="checkbox"] {
margin-right: 5px;
</style>
</head>
<body>
<div class="container">
<h2>Register</h2>
<label for="email">Email</label>
<label for="password">Password</label>
<div class="terms">
<input type="checkbox" id="terms" name="terms" required>
</div>
</form>
</div>
</body>
</html>
JAVASCRIPT
1. INTRODUCTION TO JAVASCRIPT:
What is JavaScript?
1.Client-Side Scripting
JavaScript is widely used for client-side scripting, allowing code to run directly in the user's
web browser. It can manipulate the HTML structure and CSS styles to create dynamic and
interactive user interfaces.
JavaScript works effortlessly with HTML and CSS, giving developers the ability to interact
with and manipulate the Document Object Model (DOM). This integration is key to creating
dynamic web pages and applications.
JavaScript is supported by all major browsers, including Google Chrome, Firefox, Safari,
Microsoft Edge, and others. Modern browsers ensure high compatibility and include
advanced JavaScript engines like V8 (Chrome) and SpiderMonkey (Firefox).
7.Expanding Ecosystem
JavaScript's reach goes beyond the browser with environments like Node.js for server-side
development and frameworks like React, Angular, and Vue.js for building rich, interactive
web applications.
1. Interactivity
JavaScript makes web pages dynamic and interactive, improving the overall user experience
with features like animations, real-time updates, and form validation.
2. Fast Performance
JavaScript runs directly in the browser, so it works quickly without needing to communicate
with a server for every action.
3. Versatile Usage
JavaScript is useful for both the front-end (what users see) and back-end (server-side)
development, especially with tools like Node.js.
4. Rich Features
It enables the creation of interactive elements like sliders, drag-and-drop tools, and
responsive forms, making websites more engaging.
JavaScript has a huge community of developers and plenty of tools like React, Vue.js, and
Angular that make coding easier and faster.
6. Works Everywhere
JavaScript works on all modern browsers and devices, ensuring that websites and apps
function smoothly for everyone.
4. VARIABLES IN JAVASCRIPT:
A variable is like a container that stores data in your program. You can think of it as a box
where you keep something to use later. Variables have names (labels) and values (the data
you store in them).
Declaring Variables:
Examples of Variables:
const pi = 3.14;
console.log(pi); // Output: 3.14
name = "Alice";
console.log(name); // Output: Alice
Special Notes:
1. let vs var:
o let is block-scoped (works only inside {} where it's defined).
o var is function-scoped (accessible throughout the function).
Example:
{
let x = 10;
console.log(x); // Output: 10
}
// console.log(x); // Error: x is not defined (because of block scope)
{
var y = 20;
console.log(y); // Output: 20
}
console.log(y); // Output: 20 (var is accessible outside the block)
Example:
Practical Example:
Operators are special symbols or keywords used to perform operations on variables and values.
They are essential for manipulating data, making decisions, and building logical expressions.
Here's a breakdown of the most important operators in JavaScript, explained simply and with
examples.
1. Arithmetic Operators
let sum = 5 + 3; // 8
let difference = 10 - 4; // 6
let product = 7 * 6; // 42
let quotient = 20 / 5; // 4
let x = 5;
x++; // x is now 6
let y = 8;
y--; // y is now 7
2. Assignment Operators
let a = 10; // a is 10
+= (Addition assignment): Adds the right operand to the left operand and assigns
the result.
Example:
let b = 5;
b += 3; // b is now 8
-= (Subtraction assignment): Subtracts the right operand from the left operand and
assigns the result.
Example:
let c = 10;
c -= 4; // c is now 6
let d = 7;
d *= 2; // d is now 14
/= (Division assignment): Divides the variable by the right operand and assigns the
result.
Example:
let e = 20;
e /= 4; // e is now 5
let f = 15;
f %= 4; // f is now 3
3. Comparison Operators
=== (Strict equal to): Checks if two values are equal and of the same type.
Example:
!== (Strict not equal to): Checks if two values are not equal and/or not of the same
type.
Example:
> (Greater than): Checks if the value on the left is greater than the value on the right.
Example:
< (Less than): Checks if the value on the left is less than the value on the right.
Example:
<= (Less than or equal to): Checks if the value on the left is less than or equal to
the value on the right.
Example:
4. Logical Operators
6. Other Operators
Comma Operator (,): Evaluates multiple expressions and returns the result of the
last expression.
Example:
In JavaScript, data types define what kind of value a variable can hold. Understanding the
different data types is important for working with variables, performing operations, and handling
values in your code. JavaScript has two types of data types: Primitive and Non-Primitive
(also called Reference types). Here's an easy way to understand them.
Primitive data types are the most basic types of data. They are immutable, meaning their values
cannot be changed once assigned.
1.1. Number
Example:
1.2. String
Strings are used to store text or a sequence of characters.
Example:
1.3. Boolean
Example:
1.4. Undefined
A variable that is declared but not assigned a value is automatically assigned the value
undefined.
Example:
let car;
console.log(car); // undefined
1.5. Null
Null represents the intentional absence of any value. It is used to indicate that a variable is
empty.
Example:
Symbols are unique, immutable values, often used for object properties that are guaranteed to be
unique.
Example:
BigInt is used to represent large integers that cannot be handled by the Number data type.
Example:
Non-primitive data types are more complex types. These types can store collections of data and
are mutable (their content can be changed).
2.1. Object
An object is a collection of key-value pairs, where keys are strings (or Symbols), and values can
be any data type (primitive or non-primitive).
Example:
let person = {
name: "Alice",
age: 30,
isStudent: false
};
2.2. Array
Arrays are special types of objects used to store ordered collections of data. Each element in an
array has an index starting from 0.
Example:
2.3. Function
Functions are also objects in JavaScript. A function is a block of code that can be executed and
can return a value.
Example:
function greet(name) {
return "Hello, " + name;
}
console.log(greet("John")); // Output: "Hello, John"
3. Type Conversion
Sometimes, JavaScript automatically converts between different data types, which is called type
coercion. You can also convert types manually using functions like String(), Number(), or
Boolean().
Conditional statements are used in JavaScript to perform different actions based on different
conditions. These statements allow you to make decisions in your code, helping your program to
behave differently under different situations. The most common conditional statements in
JavaScript are if, else, else if, and switch.
1. The if Statement
The if statement is used to execute a block of code only if a specified condition is true. If the
condition evaluates to true, the code inside the block will run.
Syntax:
if (condition) {
// Code to be executed if the condition is true
}
Example:
Output:
In this example, the code inside the if block runs only because the condition age >= 18 evaluates
to true.
The else statement is used alongside the if statement to specify a block of code that will be
executed if the condition is false.
Syntax:
if (condition) {
// Code to be executed if the condition is true
} else {
// Code to be executed if the condition is false
}
Example:
Output:
Here, since age is less than 18, the code inside the else block is executed.
The else if statement allows you to check multiple conditions. It comes after the if statement and
is followed by one or more conditions.
Syntax:
if (condition1) {
// Code to be executed if condition1 is true
} else if (condition2) {
// Code to be executed if condition2 is true
} else {
// Code to be executed if both conditions are false
}
Example:
Output:
In this case, since age is between 18 and 65, the else if block is executed.
The switch statement is used to check a variable or expression against a list of possible values. It
is an alternative to multiple else if statements and can be more readable when dealing with many
conditions.
Syntax:
switch (expression) {
case value1:
// Code to be executed if expression equals value1
break;
case value2:
// Code to be executed if expression equals value2
break;
default:
// Code to be executed if no case matches
}
Example:
let day = 3;
switch (day) {
case 1:
console.log("Monday");
break;
case 2:
console.log("Tuesday");
break;
case 3:
console.log("Wednesday");
break;
case 4:
console.log("Thursday");
break;
case 5:
console.log("Friday");
break;
case 6:
console.log("Saturday");
break;
case 7:
console.log("Sunday");
break;
default:
console.log("Invalid day");
}
Output:
Wednesday
In this example, the value of day is 3, so the case 3 block is executed, and "Wednesday" is
printed. The break statement is used to stop further checking once a match is found.
The ternary operator is a shorthand for an if-else statement. It evaluates a condition and returns
one of two values depending on whether the condition is true or false.
Syntax:
Example:
Output:
This is a compact version of the if-else statement. If age is 18 or more, the first message is
printed; otherwise, the second message is printed.
7. LOOPS IN JAVASCRIPT:
Loops are used to repeat a block of code multiple times in JavaScript. They are essential for
automating repetitive tasks and making your code more efficient. JavaScript provides several
types of loops, each suitable for different situations. The most common loops are for, while,
The for loop is the most commonly used loop in JavaScript. It repeats a block of code a specified
number of times. It is especially useful when you know how many times you want the loop to
run.
Syntax:
Example:
Output:
0
1
2
3
4
In this example, the for loop runs 5 times, starting from i = 0 and running as long as i < 5. After
each iteration, i is incremented by 1.
The while loop is used when you want to repeat a block of code while a specified condition is
true. The loop will continue as long as the condition evaluates to true.
Syntax:
while (condition) {
// Code to be executed
}
Example:
let i = 0;
while (i < 5) {
console.log(i); // Prints numbers from 0 to 4
i++;
}
Output:
0
1
2
3
4
In this example, the while loop continues to execute as long as i is less than 5. The counter i is
manually incremented inside the loop.
The do...while loop is similar to the while loop, but it guarantees that the code inside the loop
will be executed at least once, even if the condition is false initially.
Syntax:
do {
// Code to be executed
} while (condition);
Example:
let i = 0;
do {
console.log(i); // Prints numbers from 0 to 4
i++;
} while (i < 5);
Output:
0
1
2
3
4
Here, the code inside the do block is executed first, and then the condition i < 5 is checked. If
true, it continues; otherwise, it stops.
The for...in loop is used to iterate over the properties of an object. It loops through the keys (or
property names) of an object, one by one.
Syntax:
Example:
let person = {
name: "John",
age: 30,
city: "New York"
};
Output:
name: John
age: 30
city: New York
In this example, the for...in loop iterates over each property of the person object and logs both
the property name (key) and its corresponding value (person[key]).
The for...of loop is used to iterate over iterable objects like arrays, strings, and other collections.
It is a simpler way to iterate through values in an array or any iterable object.
Syntax:
Example:
Output:
10
20
30
40
50
In this example, the for...of loop iterates over each element in the numbers array and prints each
number one by one.
6. Breaking Out of Loops
Sometimes, you may want to stop the loop before it completes all iterations. This can be done
using the break statement, which immediately exits the loop.
Example:
Output:
0
1
2
Here, the loop stops when i reaches 3 because of the break statement.
7. Skipping an Iteration
If you want to skip the current iteration of the loop and move to the next one, you can use the
continue statement.
Example:
Output:
0
1
3
4
In this case, when i equals 2, the continue statement skips that iteration and proceeds to the next.
Template literals (also known as template strings) are a feature in JavaScript introduced in ES6
that allows you to work with strings more efficiently. Unlike regular strings, template literals
provide more powerful features, such as string interpolation, multi-line strings, and embedded
expressions, making your code cleaner and easier to understand.
Template literals are strings that are enclosed in backticks (`) instead of single or double quotes.
This allows you to embed expressions inside the string and also write multi-line strings without
needing special syntax.
Syntax:
Example:
Output:
In this example, the variables name and age are inserted directly into the string using ${}. This is
much cleaner and more readable than traditional string concatenation.
3. Multi-line Strings
Template literals also support multi-line strings, which is especially useful when you want to
include line breaks in your strings. With regular strings (using single or double quotes), you need
to use escape characters (\n) to insert new lines. With template literals, this is not necessary.
Example:
Output:
This is a string
that spans multiple lines
without using escape characters.
The string is displayed exactly as written between the backticks, preserving the line breaks.
4. Expression Embedding
Template literals allow you to embed any valid JavaScript expression inside ${}. This means you
can perform calculations or call functions directly within the string.
Example:
let num1 = 5;
let num2 = 10;
let sum = `The sum of ${num1} and ${num2} is ${num1 + num2}.`;
console.log(sum);
Output:
Here, the expression ${num1 + num2} is evaluated and the result (15) is inserted into the string.
Syntax:
tagName`template literal`;
Example:
Output:
In this example, the greet function is a tag that takes the string parts and expressions of the
template literal and returns the processed result.
You can use template literals inside other template literals, allowing for more complex string
formatting.
Example:
Output:
Example:
Complex strings: You can easily create complex strings that include calculations,
dynamic content, and expressions.
10. OBJECTS AND ARRAYS IN JAVASCRIPT:
In JavaScript, objects and arrays are two of the most commonly used data structures. They
allow you to store and manage multiple values and organize your data effectively. Let’s explore
each of them in simple terms with examples.
1. Objects in JavaScript
What is an Object?
An object in JavaScript is a collection of key-value pairs, where each key (or property) is a
string, and the value can be any type of data (such as a number, string, array, or even another
object). Objects are used to store related data and are an essential part of JavaScript.
Creating an Object
To create an object, we use curly braces {} and define properties in the format key: value.
Example:
let person = {
name: "John",
age: 30,
isStudent: false
};
console.log(person);
Output:
In this example, name, age, and isStudent are the keys (or properties), and "John", 30, and false
are the corresponding values.
Accessing Object Properties
You can access an object's properties using either dot notation or bracket notation.
Dot Notation:
console.log(person.name); // "John"
Bracket Notation:
console.log(person['age']); // 30
Note: Bracket notation is useful when the property name is dynamic or contains spaces or
special characters.
Example:
Example:
Methods in Objects
Objects can also contain methods, which are functions associated with an object.
Example:
let car = {
brand: "Toyota",
model: "Corolla",
drive: function() {
console.log("The car is driving!");
}
};
2. Arrays in JavaScript
What is an Array?
An array in JavaScript is a list-like object that can store multiple values in a single variable.
Arrays can hold elements of any type, including numbers, strings, and even other arrays or
objects.
Creating an Array
Arrays are created using square brackets [] with elements separated by commas.
Example:
Output:
Example:
console.log(fruits[0]); // "apple"
console.log(fruits[1]); // "banana"
Example:
Array Methods
Arrays have built-in methods for manipulating the elements. Here are some common ones:
ForEach:
The forEach() method allows you to execute a function for each element in the array.
fruits.forEach(function(fruit) {
console.log(fruit);
});
Output:
kiwi
blueberry
cherry
Map:
The map() method creates a new array by applying a function to each element in the original
array.
1. What is a Function?
A function is a way to define a set of instructions that can be executed whenever you call the
function. It helps to avoid repetition, making code more efficient and organized.
Function Syntax:
function functionName(parameters) {
// Code to execute
return result; // Optional return statement
}
Example:
function addNumbers(a, b) {
return a + b; // Return the sum of a and b
}
let result = addNumbers(3, 4); // Call the function with arguments 3 and 4
console.log(result); // Output: 7
In this example:
In the example above, a and b are parameters. When we call addNumbers(3, 4), the values 3
Default Parameters:
JavaScript allows you to set default values for parameters if no argument is provided.
Example:
In this case, the name parameter has a default value of "Guest", so if no argument is passed, it
uses this default value.
4. Returning Values from Functions
A function can return a value to the code that called it. The return statement specifies the value
that should be sent back.
Example:
function multiply(x, y) {
return x * y; // Multiply and return the result
}
In this example, the function returns the product of x and y, and the result is stored in the
variable result.
5. Function Expressions
In addition to defining functions using the function keyword, you can also create functions using
function expressions. This means that the function is assigned to a variable.
Example:
console.log(square(4)); // Output: 16
In this example, the function is defined and assigned to the square variable. You can then call it
like a regular function.
6. Arrow Functions (ES6)
Arrow functions are a shorter way to write functions in JavaScript. They were introduced in
ECMAScript 6 (ES6) and are commonly used in modern JavaScript development.
Syntax:
Example:
In this example, add is an arrow function that adds two numbers. Arrow functions are often
preferred for their simplicity, especially when the function body is simple.
7. Function Scope
In JavaScript, scope refers to the context in which a variable or function is accessible. Variables
declared inside a function are local to that function and cannot be accessed outside it.
Example:
function greet() {
let greeting = "Hello, world!"; // Local variable
console.log(greeting); // This will work
}
greet();
console.log(greeting); // This will result in an error, because greeting is not accessible outside
the function.
In this example, the variable greeting is defined inside the function greet, so it is not accessible
outside the function.
8. Function Hoisting
In JavaScript, function declarations are hoisted. This means they are moved to the top of their
scope during the compilation phase, allowing you to call a function before it is defined in the
code.
Example:
function greet() {
console.log("Hello!");
}
However, function expressions are not hoisted. So, trying to call a function defined with a
function expression before it’s declared will result in an error.
9. Callback Functions
A callback function is a function that is passed as an argument to another function and is
executed after the completion of that function.
Example:
function farewell() {
console.log("Goodbye!");
}
In this example, the greet function accepts a callback (farewell), and it is called after the greeting
is printed.
10. Recursion
Recursion is a programming technique where a function calls itself in order to solve a problem.
Example:
function factorial(n) {
if (n === 0) {
return 1; // Base case
}
return n * factorial(n - 1); // Recursive call
}
console.log(factorial(5)); // Output: 120
In this example, the factorial function calculates the factorial of a number by calling itself until it
reaches the base case (n === 0).
1. What is an Event?
An event in JavaScript is an action or occurrence that the browser recognizes, such as a mouse
click, keyboard press, page load, or form submission. Events are used to interact with the user
and trigger functions when certain conditions are met.
For example, when a user clicks a button on a webpage, a "click" event occurs, and you can set
up JavaScript to respond to that event.
There are many different types of events in JavaScript. Some of the most common events
include:
Page Events:
Form Events:
2. Event Listener
You can define events directly within HTML elements using attributes. This is the simplest
method but is generally not recommended for large projects due to separation of concerns.
Example:
In this example, when the user clicks the button, the event handler onclick triggers a JavaScript
alert().
3.2 Event Listener
The most modern and preferred way of handling events is by using addEventListener(). This
method allows you to attach an event handler to an element, enabling multiple event listeners to
be added to the same element.
Syntax:
Example:
<script>
let button = document.getElementById("myButton");
button.addEventListener("click", function() {
alert("Button clicked!");
});
</script>
In this example, when the user clicks the button, an alert box will appear, showing the message
"Button clicked!".
Example:
<script>
let button = document.getElementById("myButton");
button.onclick = function() {
alert("Button clicked!");
};
</script>
In this example, when the button is clicked, the assigned function will run and show an alert.
4. Event Object
When an event occurs, the browser automatically passes an event object to the event handler.
This object contains information about the event, such as which element triggered the event and
any additional data (e.g., mouse coordinates or key code).
Example:
<script>
let button = document.getElementById("myButton");
button.addEventListener("click", function(event) {
console.log(event); // Logs the event object
console.log("Button clicked!");
});
</script>
In this example, the event object is logged when the button is clicked, providing details such as
the mouse position, the type of event, and the target element.
5. Event Propagation
1. Capturing Phase (Event travels down from the root to the target element).
2. Bubbling Phase (Event travels up from the target element to the root).
You can control how an event propagates by using stopPropagation() and preventDefault().
Example:
<div id="parentDiv">
<button id="childButton">Click Me</button>
</div>
<script>
document.getElementById("parentDiv").addEventListener("click", function(event) {
alert("Parent Div clicked!");
event.stopPropagation(); // Stop the event from bubbling
});
document.getElementById("childButton").addEventListener("click", function() {
alert("Button clicked!");
});
</script>
In this example:
When you click the button, the click event triggers on the button first.
Then, the event would bubble to the parent div, but stopPropagation() prevents it, so only
the button’s alert will show.
You can remove an event listener from an element using the removeEventListener() method.
This is useful if you no longer want the event to trigger after a certain condition is met.
Example:
<script>
let button = document.getElementById("myButton");
function handleClick() {
alert("Button clicked!");
}
button.addEventListener("click", handleClick);
In this example, the click event listener is removed after 3 seconds, so after that, clicking the
button will not trigger the alert.
7. Event Delegation
Event delegation is a technique where you attach a single event listener to a parent element, and
the event listener will handle events for child elements as well. This is useful when you have
multiple child elements, and you don't want to attach an individual event listener to each one.
Example:
<ul id="myList">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
<script>
let list = document.getElementById("myList");
list.addEventListener("click", function(event) {
if (event.target.tagName === "LI") {
alert("List item clicked: " + event.target.textContent);
}
});
</script>
In this example, a single click event listener is attached to the ul element, but it listens for clicks
on any of the li elements. This is an example of event delegation.
13. DOM MANIPULATION IN JAVASCRIPT:
DOM manipulation refers to the process of accessing and modifying the elements of a web page
using JavaScript. Through DOM manipulation, you can:
In simple terms, DOM manipulation allows you to update the structure and appearance of a
webpage after it has loaded.
To manipulate elements in the DOM, you first need to select them. JavaScript provides several
methods for selecting elements:
getElementById()
getElementsByClassName()
Selects elements by their class name. It returns a live HTMLCollection (array-like object).
querySelector()
querySelectorAll()
Selects all matching elements using a CSS selector, returning a static NodeList.
You can change the text inside an element using the textContent property:
You can modify an element's attributes (like src, href, etc.) using setAttribute():
You can change the styles of elements dynamically by modifying the style property:
To add new elements, use createElement() to create the new element and appendChild() or
insertBefore() to insert it into the DOM.
let newElement = document.createElement("p");
newElement.textContent = "This is a new paragraph!";
let parentElement = document.getElementById("parentDiv");
parentElement.appendChild(newElement);
Removing Elements
Alternatively, you can use the remove() method on the element itself:
JavaScript allows you to attach event listeners to elements, enabling interaction with the page
(e.g., when a user clicks a button or submits a form).
Let’s look at a simple example where we manipulate the DOM by adding a new element,
changing the content, and responding to user interaction.
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>DOM Manipulation Example</title>
</head>
<body>
<div id="parentDiv">
<button id="addButton">Add New Item</button>
</div>
<script src="script.js"></script>
</body>
</html>
JavaScript (script.js):
In this example:
When the "Add New Item" button is clicked, a new <p> element is created.
The new paragraph has the text "This is a new item!" and is styled with the color green.
The new item is then appended to the parentDiv on the webpage.
1. Promises
A Promise is an object that represents the eventual completion (or failure) of an asynchronous
operation and its resulting value.
You can create a Promise using the Promise constructor, which accepts a function with two
parameters: resolve (for success) and reject (for failure).
2. Async/Await
The Async/Await syntax is a more concise and readable way to handle Promises. It allows
you to write asynchronous code that looks and behaves like synchronous code.
A function prefixed with async always returns a Promise. If the function explicitly returns a
value, it is wrapped in a resolved Promise.
The await keyword pauses the execution of an async function until the Promise is resolved or
rejected. It can only be used inside async functions.
processData();
Error handling in async/await is done using try...catch blocks. This makes error handling
straightforward and similar to synchronous code.
function fetchData(success) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (success) resolve("Data fetched successfully!");
else reject("Failed to fetch data.");
}, 2000);
});
}
processData();
Using Promises
fetch("https://jsonplaceholder.typicode.com/posts/1")
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error("Error:", error));
Using Async/Await
Static typing:
You can define types for variables, parameters, and return values.
Compile-time checks:
TypeScript ensures that types are used correctly before running the
code.
Works everywhere JavaScript runs:
TypeScript can be compiled to standard JavaScript, which runs in all
browsers, environments, and platforms.
Support for modern JavaScript features:
TypeScript supports many ES6 and ES2015 features such as classes,
modules, and async/await.
DATATYPES:
1. String
Strings represent textual data. In TypeScript, a string is defined using either single quotes
(') or double quotes (").
You can store any text in a string variable.
Example:
2. Number
In TypeScript, all numbers (integers, floating-point values) are represented by the number
type.
It also supports decimal, hexadecimal, binary, and octal literals.
Example:
3. Boolean
Example:
4. Array
5. Tuple
Tuples are arrays where each element can have a different type, and their number and
order are fixed.
For example, a tuple can store a string followed by a number.
Example:
6. Any
The any type is used when you don’t want to specify a type, or when the type of a value
is unknown.
It allows variables to hold values of any type, effectively opting out of TypeScript's type-
checking.
Example:
let data: any = 'Hello';
data = 100;
7. Enum
Example:
enum Color {
Red = 1, // 1
Green, // 2
Blue, // 3
}
const myColor: Color = Color.Green;
console.log(myColor); // Prints: 2
8. Void
The void type is used for functions that don’t return a value.
It's similar to null or undefined, but it's used specifically for functions.
Example:
console.log(message);
FUNCTIONS:
Functions in TypeScript work the same as JavaScript functions but with type annotations for
parameters and return types.
1. BASIC FUNCTION
Example:
if (age) {
} else {
}
console.log(greetWithAge('Alice')); // Prints: Hello, Alice!
3. FUNCTION TYPE
You can specify the function signature with explicit parameter types and return types.
Example:
4. RETURN TYPE
The return type of a function is explicitly defined after the parameter list.
TypeScript can also infer the return type in many cases.
Example:
return a * b;
OBJECTS :
DEFINING OBJECTS
Example:
name: 'Alice',
age: 30
};
In this case, user is an object where the name is a string and the age is a number.
TypeScript will throw an error if you try to assign values of incorrect types.
user = {
};
COMPLEX OBJECTS:
Example:
};
Here, complexObject has two properties:
data, which is an array of numbers.
transform, which is a function that takes a number as input and returns a number.
TypeScript allows you to define optional properties in objects using the ? syntax.
This means that the property may or may not be present in the object.
Example:
name: 'John'
};
name: 'Sarah',
age: 25
};
In this case, the age property is optional. You can define an object with only the name
property, and TypeScript will not complain.
If the age property is provided, it must be a number.
ALIASES:
TypeScript allows you to create aliases for complex types, which helps in avoiding repetitive
code and improving readability.
Example:
name: 'Peter',
role: 'Developer',
age: 28
};
In this case, Employee is a type alias for objects that have a name, role, and age property.
You can reuse the Employee type wherever needed.
UNION TYPES:
TypeScript provides the ability to define a variable that can hold multiple types.
This is called a union type. You can use the | operator to specify that a value can be one
of several types.
Example:
Example:
name: 'Emily',
details: 30
Here, the details property can be either a string or a number, and TypeScript will enforce that
when assigning values to it.
INTERSECTION TYPES :
An intersection type is defined using the & operator, and it creates a new type that
contains all the properties from the types involved.
This is similar to combining features from multiple classes or interfaces into a single
class.
The resulting type will have the properties of both types, as long as the types do not
conflict.
For example, if you want to combine a Person type and a Loggable interface into a new
LoggablePerson type,
you could write:
interface Loggable {
interface Person {
name: string;
age: number;
isStark?: boolean;
};
age: 23,
log: logPerson,
};
In this example, the LoggablePerson type combines the properties of Person and Loggable,
meaning jonSnow has the properties name, age, isStark, and a method log.
Intersection types can only combine types that are structurally compatible.
If two types have properties with conflicting structures, they cannot be combined.
For instance, trying to intersect string and number types will result in an error because
they are incompatible
let stringAndNumber: string & number = 5; // Error: Type 'number' is not assignable to type
'string'.
This happens because TypeScript checks if types are compatible by comparing their
properties.
Since string and number don't share compatible properties, the intersection type fails.
class Animal {
name: string;
name: "Cheetah",
};
console.log(cheetah.name); // Cheetah
In this case, RunningAnimal combines both the Animal class and the Runner interface, resulting
in a new type that has both the name property and the run method.
In TypeScript, you can use type guards to check the type of a variable at runtime.
This is done using typeof for primitive types or instanceof for object types.
Example:
console.log("Value is a string");
Here, typeof ensures that the code block only runs if value is indeed a string.
Example:
Since the function always throws an error, it never returns a value, making its return type never.
NULLABLE TYPES
In TypeScript, you can explicitly define a variable that can either be null or another type,
using union types.
This helps represent cases where a value might be absent.
Example:
Type assertions allow you to tell TypeScript to treat a value as a specific type when you
know more about its type than TypeScript can infer.
This is useful when working with any types.
There are two syntaxes for type assertions:
Angle bracket syntax (works in most situations):
TypeScript supports modern JavaScript features like arrow functions, template literals,
destructuring, and more.
These features work seamlessly with TypeScript’s type system.
Arrow functions are concise and can accept types for their parameters:
console.log(`Hello, ${name}`);
};
console.log(`Hello, ${name}`);
};
Spread Operator
console.log(Math.max(...numbers)); // Prints: 3
DESTRUCTURING
console.log(firstScore, secondScore); // 90 85
For objects:
ANGULAR
HISTORY OF ANGULAR:
Angular 2.0 was first announced at the ng-Europe conference on October 22-23, 2014.
NAMING CLARIFICATION:
To avoid confusion, the rewrite of AngularJS was named Angular 2, but the community
later clarified that AngularJS refers to versions 1.X, while Angular (without "JS") refers
to version 2 and later.
It has become one of the most widely used frameworks, with over 1.7 million developers
contributing to its ecosystem.
Prerequisites:
Before you can start developing with Angular, you need to have Node.js installed on your
machine.
Node.js comes with NPM (Node Package Manager), which is used to install the required
Angular packages and dependencies.
NPM:
Yarn:
Once installed, you can create a new Angular project with the following command:
ng new my-app
Project Setup:
When you run the above command, Angular will prompt you for some configuration
options (e.g., adding Angular routing, choosing stylesheets like CSS or SCSS).
After confirming your choices, Angular will set up a new project with the default
configurations.
ng serve
ng build –prod
n an Angular project, the directory structure is designed to keep the project organized and
maintainable.
Each folder within an Angular project serves a specific purpose, helping developers
efficiently structure their code, manage assets, and separate concerns.
Below is a breakdown of the typical folders you will encounter in an Angular project and
what they are used for.
When you create a new Angular project using the Angular CLI, you'll see the following default
structure at the root level:
my-app/
├── node_modules/
├── src/
├── angular.json
├── package.json
├── tsconfig.json
├── tsconfig.app.json
├── tslint.json
├── e2e/
└── .gitignore
2. src/ Folder
The src/ folder (short for "source") is where most of your application’s code resides. This
includes the core application logic, components, templates, and styles. When you build the
application, Angular will bundle everything in this folder into the final output.
Inside the src/ folder, you'll typically find the following subfolders:
This is the most important folder in an Angular project as it contains the main code for your
application, including:
Components: Reusable UI elements of your app. Each component typically includes a .ts file
(TypeScript), a .html file (template), a .css/.scss file (styling), and a .spec.ts file (for testing).
Example: src/app/my-component/my-component.component.ts
Services: Services are classes that encapsulate business logic, data retrieval, or any reusable
functionality that can be shared across components.
Example: src/app/services/data.service.ts
Modules: Angular modules are used to group related components, services, pipes, etc., into
functional units. The root module of your Angular application is called AppModule, located in
src/app/app.module.ts.
Example: src/app/app.module.ts
Routing: If your application has multiple views or pages, the routing module (app-
routing.module.ts) handles navigation and route management.
Example: src/app/app-routing.module.ts
The assets/ folder holds static files such as images, stylesheets, icons, fonts, and any other non-
code resources that need to be served by the application. It is commonly used to store:
Example:
src/assets/
├── images/
├── icons/
├── styles/
└── data/
These files are publicly accessible and can be referenced in templates or styles.
This folder contains environment configuration files that are used to define different
settings for different environments (e.g., development, production).
environment.ts: The default environment settings for development.
environment.prod.ts: The production environment settings.
These files help configure settings like API URLs, logging levels, and feature flags based
on the environment the application is running in.
Angular uses the fileReplacements option in the angular.json file to switch between these
files during builds.
Example:
src/environments/
If you're using global styles across your app, the styles/ folder is where they go.
This folder can contain CSS, SCSS, or any other stylesheet you use globally in the app.
styles.css (or styles.scss): The main global stylesheet file for your project.
Example:
src/styles/
└── styles.css
2.5. src/favicon.ico
This file represents the favicon (the small icon displayed in the browser tab) for the
application.
It's a default file placed in the root src/ folder.
2.6. src/main.ts
2.7. src/polyfills.ts
This file is used to include polyfills that enable the app to run on older browsers.
It ensures compatibility with browsers that don't support some modern JavaScript
features natively (e.g., older versions of Internet Explorer).
The e2e/ folder contains the configuration and code for end-to-end testing of the Angular
application.
These tests simulate user interactions with the application, ensuring the entire system
works as expected from a user's perspective.
Protractor is typically used for e2e testing in Angular, and the configuration files and test
scripts are stored in this folder.
Example:
e2e/
├── src/
4.1. angular.json
This is the main configuration file for an Angular project. It defines settings like:
Project structure
4.2. package.json
This file lists all the dependencies (both development and production), scripts, and
metadata for the project.
It is where you define npm scripts to run Angular CLI commands like ng serve, ng build,
etc.
4.3. tsconfig.json
This TypeScript configuration file defines how TypeScript files should be compiled.
It includes options like paths, module resolution, and target ECMAScript versions.
4.4. tsconfig.app.json
4.5. tslint.json
4.6. .gitignore
This file tells Git which files and directories to ignore when committing to a repository.
It typically includes directories like node_modules, build artifacts, and IDE-specific files.
5. node_modules/ Folder
This folder is created when you install dependencies using npm install.
It contains all the libraries and packages that the Angular project depends on.
You should not manually modify files in node_modules/, as they are automatically
managed by npm.
dist/ folder:
After running the build command (ng build), Angular compiles the project and stores the
final, optimized production files (HTML, JavaScript, CSS) in the dist/ directory.
This is the folder that gets deployed to production.
COMPONENTS IN ANGULAR:
Command:
or
ng g c MyNewComponent
When you run either command, Angular will create the component files in a directory named
after the component.
my-new-component.component.html :
The template file containing the HTML structure displayed when the component is
rendered.
my-new-component.component.css:
my-new-component.component.ts:
my-new-component.component.spec.ts:
A test file for validating the behavior and output of the component.
Additionally, the component's class is automatically decorated with the @Component decorator
and registered with the nearest Angular module.
Here are some helpful options you can use with the Angular CLI when creating components:
Simulates the command without creating files. Useful for previewing changes.
--help ng g c –help:
Angular components go through a series of lifecycle stages, emitting events at each stage.
Developers can hook into these events by implementing specific methods in the
component class.
ngOnChanges
ngOnInit
Called once the component is initialized and input bindings are ready.
ngDoCheck
ngAfterContentInit
ngAfterContentChecked
ngAfterViewInit
Invoked after the component's view and child views are fully initialized.
ngAfterViewChecked
Runs after every check of the component's view and its child views.
ngOnDestroy
Called before the component is removed or destroyed. Useful for cleanup tasks
like unsubscribing from observables.
This is commonly used to initialize component data or perform setup tasks like fetching
data.
ngOnInit(): void {
console.log('Component Initialized');
this.fetchUserData();
ngOnChanges
It is especially useful when a parent component passes new data to a child component.
if (changes['userName']) {
ngOnDestroy
This is used for cleanup, such as unsubscribing from observables or clearing timers.
ngOnDestroy(): void {
this.subscription.unsubscribe();
}
In Angular, services are objects designed for outsourcing reusable logic and data that can
be shared across multiple components or modules.
Services enable cleaner, modular, and more maintainable code, making them essential for
medium and large-scale applications.
For medium-sized apps, services can even act as a lightweight alternative to state
management libraries.
Standard Command:
or
ng g s MyService
Services are not standalone; they are meant to be injected into other parts of the app, such
as components, directives, or other services.
To make a class a service and injectable, you need to follow these two steps:
The @Injectable() decorator marks a class as a service and makes it available for dependency
injection.
@Injectable()
constructor() { }
After making the class injectable, you need to tell Angular where the service should be
available.
Injectable at the Root Level The most common method is to provide the service in the
root injector. This ensures the service is a singleton and accessible throughout the
application.
@Injectable({
})
Advantages:
@NgModule({
declarations: [],
imports: [],
bootstrap: []
})
Use Case:
@Component({
selector: 'app-my-component',
templateUrl: './my-component.component.html',
styleUrls: ['./my-component.component.css'],
})
Use Case:
When a service should have a separate instance for each component (e.g., for component-specific
state management).
MODULES :
Classes decorated with the @NgModule() decorator can register components, services,
directives, and pipes.
declarations - List of components, directives, and pipes that belong to this module.
imports - List of modules to import into this module. Everything from the imported modules is
available to declarations of this module.
exports - List of components, directives, and pipes visible to modules that import this module.
providers - List of dependency injection providers visible both to the contents of this module and
to importers of this module.
@NgModule({
declarations: [ AppComponent ],
providers: [],
bootstrap: [AppComponent]
})
ANGULAR DIRECTIVES:
Directives are custom attributes that can be applied to elements and components to
modify their behavior.
There are two types of directives:
attribute directives
structural directives
ATTRIBUTE DIRECTIVES:
NgClass
NgStyle
<div [ngStyle]="{
}">
</div>
NgModel
Firstly, this directive requires the FormsModule to be added to the @NgModule() directive.
/* . . . */
@NgModule({
/* . . . */
imports: [
BrowserModule,
],
/* . . . */
})
Secondly, we can bind the [(ngModel)] directive on an HTML <form> element and set it equal
to the property.
<label for="example-ngModel">[(ngModel)]:</label>
The `NgModel` directive has more customizable options that can be [found
here](https://angular.io/guide/built-in-directives#displaying-and-updating-properties-with-
ngmodel).
STRUCTURAL DIRECTIVES:
Structural directives are directives that change the DOM layout by adding and removing
DOM elements.
Here are the most common structural directives in Angular:
NgIf
A directive that will conditionally create or remove elements from the template. If the value of
the NgIf directive evaluates to false, Angular removes the element.
NgFor
NgSwitch
NgSwitch — A structural directive that should be assigned the value that should be
matched against a series of conditions.
NgSwitchCase — A structural directive that stores a possible value that will be matched
against the NgSwitch directive.
<ul [ngSwitch]="food">
<li *ngSwitchCase="'Burger'">Burger</li>
<li *ngSwitchCase="'Pizza'">Pizza</li>
<li *ngSwitchCase="'Spaghetti'">Spaghetti</li>
CUSTOM DIRECTIVES
@Directive({
})
@HostListener('mouseenter') onMouseEnter() {
}
// Listen to mouseleave event
@HostListener('mouseleave') onMouseLeave() {
@Directive Decorator:
Defines the directive with the selector, which is used as an attribute in templates.
@Input Decorator:
Allows the directive to accept input properties for customization (e.g., setting a dynamic
highlight color).
@HostListener Decorator:
Listens to events (e.g., mouseenter, mouseleave) on the host element and triggers
specified methods.
ElementRef gives access to the DOM element where the directive is applied.
Renderer2 provides a safe way to modify the DOM (e.g., setting styles).
<br>
<br>
Make sure the directive is declared in the AppModule or the relevant feature module:
app.module.ts:
@NgModule({
declarations: [
AppComponent,
],
imports: [BrowserModule],
providers: [],
bootstrap: [AppComponent]
})
ng serve
Expected Behavior:
When you hover over the first <div>, its background changes to light blue.
When you hover over the second <div>, its background changes to light green.
When you hover over the third <div>, its background changes to the default yellow.
The background color resets when you move the mouse away.
PIPES :
Pipes in Angular are used to transform displayed content in templates without altering the
actual data.
They are especially handy for formatting or transforming data on the fly.
Pipes are applied in templates using the | symbol.
DatePipe
Formats a date value according to locale-specific rules.
You can specify formats like 'short', 'medium', 'long', or even custom formats.
Example:
{{ '2024-11-28T15:30:00' | date:'fullDate' }}
UpperCasePipe
Example:
LowerCasePipe
Example:
CurrencyPipe
Example:
{{ 1234.56 | currency:'EUR' }}
Output: €1,234.56
DecimalPipe
Example:
{{ 7.56789 | number:'1.1-3' }}
Output: 7.568
Explanation: At least 1 digit before the decimal, 1-3 digits after the decimal.
PercentPipe
Example:
{{ 0.4567 | percent:'1.0-2' }}
Output: 45.67%
Example:
Output: ANGULAR
Explanation: The string is transformed to uppercase and then sliced to display only the first 7
characters.
FORMS :
Angular provides two approaches to handling forms:
Template-driven forms
Reactive forms.
Both approaches offer powerful features for gathering user input, performing validations, and
managing form state, but they differ in their structure and implementation style.
1. TEMPLATE-DRIVEN FORMS:
Template-driven forms are forms where most of the logic is handled in the HTML
template.
They are suitable for simpler forms and are declarative in nature.
Key Features:
Two-way Data Binding: Template-driven forms use ngModel to bind form elements to
properties in the component.
Automatic Validation: Validation is done through the template by using Angular's built-in
directives.
Example:
<label for="name">Name:</label>
<label for="email">Email:</label>
// app.component.ts
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
In this example:
2. REACTIVE FORMS:
Reactive forms provide a more programmatic approach to form creation, allowing the form
model to be created and controlled within the component. This approach is more flexible and
scalable, suitable for complex forms.
Key Features:
Reactive Programming: Reactive forms are based on the FormControl and FormGroup classes.
Manual Form Control: Form fields are explicitly defined in the component class using
FormControl and FormGroup.
Form Validation: You can define synchronous and asynchronous validators in the component.
Example:
// app.component.ts
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
myForm: FormGroup;
this.myForm = this.fb.group({
});
onSubmit(): void {
if (this.myForm.valid) {
<label for="name">Name:</label>
</form>
In this example:
3. Form Validation
Form validation in Angular can be done either declaratively (in templates) or programmatically
(in the component). Both template-driven and reactive forms support built-in validation.
Built-in Validators:
this.myForm = this.fb.group({
});
You can check the validation status using valid, invalid, pending, or touched properties:
</div>
FormControl: Represents an individual form control (like an input field). It tracks the value and
validation status of the input.
FormGroup: A group of related FormControl instances. It tracks the validity and value of a group
of controls.
name: this.nameControl,
});
You can access individual controls using this.myForm.get('controlName') and apply validations
or retrieve values.
5. Custom Validators
Custom validators allow you to implement your own validation logic beyond the built-in
validators.
};
You can apply the custom validator as part of the form control:
this.myForm = this.fb.group({
});
In this example, the custom validator checks if the input contains the forbidden word "admin".
For asynchronous validation (like checking if an email already exists), you can create an async
validator using observables.
import { Observable, of } from 'rxjs';
.pipe(debounceTime(500));
DECORATORS IN ANGULAR :
Decorators in Angular are special functions used to enhance classes, methods, properties,
or parameters.
They provide metadata that Angular uses to understand and configure the behavior of the
class or element to which they are applied.
Angular heavily relies on decorators for its core features, such as components, services,
and modules. Decorators are a TypeScript feature and are prefixed with an @ symbol.
1. Class Decorators
These are the most common decorators in Angular, such as @Component, @Directive,
and @NgModule.
Example:
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
Example:
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule],
bootstrap: [AppComponent]
})
Example:
@Component({
selector: 'app-child',
})
Example:
@Component({
selector: 'app-child',
template: `<button (click)="sendData()">Send Data</button>`
})
sendData() {
} }
3. Method Decorators
Example:
@HostListener('mouseenter') onMouseEnter() {
console.log('Mouse entered!'); }
@HostListener('mouseleave') onMouseLeave() {
console.log('Mouse left!');
}
4. Parameter Decorators
Example:
@Component({
selector: 'app-root',
})
console.log(this.document);
5. Accessor Decorators
Example:
function LogAccess(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
descriptor.get = function () {
return originalGet.apply(this);
};
class Example {
@LogAccess
get value() {
return this._value;
ROUTING IN ANGULAR
The Angular Router is a module in Angular that allows you to define routes for
navigating between views.
It maps browser URLs to components and ensures the correct component is displayed
based on the current route.
To enable routing in an Angular application, you need to import the RouterModule from
@angular/router and configure the routes.
2. Setting up Routes
Example:
// app-routing.module.ts
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
In this example:
The home page is mapped to the empty path (''), which serves as the default route.
The about route maps to the AboutComponent.
Route guards are special services in Angular that allow you to control access to routes.
They act as protection mechanisms and are useful for scenarios like authentication,
confirming navigation, or preventing unsaved changes from being discarded.
CanActivate: Prevents navigation to a route based on specific conditions. For example, you can
check if the user is logged in before allowing access to a certain route.
CanDeactivate: Prevents leaving a route based on conditions, such as confirming if a user has
unsaved changes.
@Injectable({
providedIn: 'root',
})
if (this.authService.isAuthenticated()) {
return true;
} else {
this.router.navigate(['/login']);
return false;
In this example, the AuthGuard checks if the user is authenticated before allowing access to a
route.
@Injectable({
providedIn: 'root',
})
This guard is useful when a user is trying to navigate away from a page with unsaved changes. If
the component implements the CanComponentDeactivate interface, it can return a confirmation
prompt before leaving.
Nested routes (also known as child routes) allow you to create routes inside other routes.
This is useful for creating hierarchical UI structures.
You can define nested routes by placing them inside the children array of a parent route.
Example:
path: 'profile',
component: ProfileComponent,
children: [
],
},
];
In this example, the ProfileComponent is the parent route, and it has two child routes:
details and settings.
The child routes will be displayed in the <router-outlet> inside the ProfileComponent.
Template Example:
<h2>Profile</h2>
<router-outlet></router-outlet>
Here, the <router-outlet> will be used to display the child routes (ProfileDetailsComponent and
ProfileSettingsComponent) based on the active route.
HTTP AND OBSERVABLES :
Angular provides a powerful HttpClient module to interact with remote servers via HTTP
requests.
This module uses Observables (from RxJS, Reactive Extensions for JavaScript) to handle
asynchronous operations like HTTP requests, making it easier to manage response data,
handle errors, and chain multiple HTTP operations.
1. HttpClient Module
The HttpClient module is part of Angular’s HTTP package and provides a simplified API
for making HTTP requests.
It uses Observables for handling asynchronous responses, which allows for more
powerful composition and manipulation of HTTP responses.
Key Features:
Type Safety: You can define the expected response type, making it easier to handle data.
Rich APIs: Supports methods for various HTTP operations (GET, POST, PUT, DELETE, etc.).
RxJS Support: Returns RxJS Observable objects that can be piped, mapped, and subscribed to,
enabling reactive programming.
To use HttpClient, you need to import the HttpClientModule in your Angular module
(AppModule).
@NgModule({
imports: [HttpClientModule],
})
@Injectable({
providedIn: 'root',
})
getData(): Observable<any> {
return this.http.get('https://api.example.com/data');
In this example:
this.http.get('https://api.example.com/data')
.subscribe(response => {
});
this.http.post('https://api.example.com/data', newData)
.subscribe(response => {
});
In both cases, the HTTP methods return an Observable which you can subscribe to, handle the
response data, or catch errors.
this.http.get('https://api.example.com/data')
.pipe(
map((response: any) => response.items) // Extracting the 'items' from the response
.subscribe(items => {
console.log('Items:', items);
});
this.http.get('https://api.example.com/data')
.pipe(
catchError(error => {
.subscribe();
In this example:
The catchError operator is used to handle errors from the HTTP request, ensuring that
your application can gracefully handle failures.
map is used to transform the response data before subscribing to it.
Handling responses and errors effectively is a critical part of working with HTTP
requests.
The HttpClient makes it easy to deal with HTTP responses by returning an Observable
that emits the response.
This allows developers to react to different scenarios like success, failure, or retries.
When an HTTP request is successful, the Observable emits the response data. You can access
this data in the subscribe() method's callback function.
this.http.get('https://api.example.com/data')
.subscribe(response => {
});
Error Handling
If the request fails (e.g., due to a 404 or network issue), you can catch the error using the
catchError operator and handle it appropriately (e.g., displaying an error message to the user).
import { catchError } from 'rxjs/operators';
this.http.get('https://api.example.com/data')
.pipe(
catchError(error => {
console.error('Error:', error);
})
.subscribe(
data => {
console.log('Data:', data);
},
error => {
);
In this example:
If an error occurs (e.g., network failure or 404 error), it is caught and handled by the
catchError operator.
The throwError() function re-throws the error or provides a fallback value.
5. HTTP Interceptors
An HTTP Interceptor is a powerful feature in Angular that allows you to modify HTTP requests
or responses globally, before they reach the server or the component that made the request.
Adding Authorization Headers: You can attach JWT tokens to the headers of all
outgoing requests.
Logging: Log all HTTP requests and responses for debugging or auditing.
Error Handling: Globally catch errors from all HTTP requests.
Request Modification: Modify requests before they are sent to the server (e.g., adding
timestamps or modifying request body).
@Injectable()
});
return next.handle(clonedRequest);
}}
In this example:
@NgModule({
providers: [
provide: HTTP_INTERCEPTORS,
useClass: AuthInterceptor,
multi: true,
})
The multi: true option ensures that multiple interceptors can be used together.
INTRODUCTION
Java Platform, Enterprise Edition (Java EE) has revolutionized the way web applications are
built. It evolved from the need for a robust, scalable, and secure platform for enterprise-level
development. Java EE extends the capabilities of Java SE by providing APIs and runtime
environments for distributed and web-based applications. It simplifies the development process
by offering reusable components, integration with databases, and support for web services.
A diagram showing the core components like Servlets, JSP, EJB, and Web Services interacting
with the database and client.
Java EE is the backbone of countless web applications across various domains such as e-
commerce, healthcare, and finance. Its platform independence, coupled with features like
security, scalability, and extensive community support, makes it a preferred choice for
developers. Applications built on Java EE can cater to millions of users, ensuring high
performance and reliability.
JAVA EE LAYERS
Depict layers such as Presentation Layer (JSP/Servlets), Business Logic Layer (EJB),
Servlets are the cornerstone of Java EE web development. They provide a simple yet powerful
mechanism for building server-side components. Servlets enable developers to handle requests
and generate responses dynamically. They form the basis of most web frameworks, offering
flexibility and extensibility.
JDBC (Java Database Connectivity) is an integral part of Java EE, enabling interaction between
Java applications and relational databases. It allows developers to execute SQL queries, retrieve
results, and manage transactions programmatically. JDBC ensures that Java EE applications can
efficiently persist and fetch data from the database layer.
JDBC FLOW
Show how an application connects to a database through JDBC drivers, executes queries, and
retrieves results.
JavaServer Pages (JSP) complements Servlets by allowing developers to embed Java code within
HTML to create dynamic web pages. JSP is particularly effective for generating user interfaces
while delegating business logic to Servlets or EJBs. Its integration with Expression Language
(EL) and custom tags simplifies web development.
The true power of Java EE lies in the seamless integration of its components. By combining
Servlets for request handling, JSP for presentation, and JDBC for database interaction,
developers can build robust, maintainable, and scalable web applications. The framework’s
modularity ensures adaptability to changing business needs.
This introduction establishes the foundation for understanding the Java EE ecosystem, its
components, and its pivotal role in modern web development. Each diagram complements the
textual content, providing a visual guide to the concepts discussed.
Java Database Connectivity (JDBC) is a Java API that enables Java applications to interact with
relational databases. JDBC provides methods for querying and updating data in a database,
enabling developers to execute SQL statements from Java code. It abstracts the interaction
between a Java application and a database, providing a standard interface for database
operations.
COMPONENTS OF JDBC
1. JDBC Drivers: These are Java classes that implement the JDBC interfaces, enabling
Java applications to connect to different types of databases.
2. DriverManager: A class that manages a list of database drivers. It helps in selecting
an appropriate driver for database communication.
3. Connection: An interface representing an open connection to a database. It allows for
creating statements, committing or rolling back transactions, and closing the connection.
4. Statement: An interface used to execute SQL queries against a database.
7. ResultSet: Represents the result of a query. It holds the data retrieved from the
database, which can be accessed using various methods like next(), getInt(), and
getString().
TYPES OF JDBC DRIVERS
There are four main types of JDBC drivers, each with its advantages and use cases:
1. Type 1 – JDBC-ODBC Bridge Driver: This driver uses the ODBC (Open
Database Connectivity) driver to interact with the database. It is not commonly used
anymore due to performance issues and lack of support in newer Java versions.
2. Type 2 – Native-API Driver: This driver converts JDBC calls into database-
specific calls using native libraries. It is faster than Type 1 but still requires installation of
database client software.
3. Type 3 – Network Protocol Driver: This driver communicates with a middleware
server that translates JDBC calls into database-specific calls. It doesn't require a client
installation on the machine where the application runs.
4. Type 4 – Thin Driver: This driver converts JDBC calls directly into database-
specific calls using a pure Java implementation. It is the most efficient and widely used
type of driver in modern applications.
To interact with a database in JDBC, the first step is to establish a connection. This can be done
using the DriverManager.getConnection() method, which accepts the database URL, username,
and password. Here's an example:
Once the connection is established, you can perform various database operations like querying or
updating data.
JDBC API METHODS WITH EXAMPLES
5. close(): Used to close the ResultSet, Statement, and Connection objects to release
resources.
rs.close();
stmt.close();
con.close();
SERVLETS
INTRODUCTION TO SERVLETS
A Servlet is a Java program that runs on a web server and extends the capabilities of a server.
Servlets are primarily used to create dynamic web applications, handling client requests,
processing them, and sending back the appropriate response.
Servlets are part of the Java EE (Enterprise Edition) and serve as the foundation for web
applications in Java. A servlet is executed in response to client requests, typically through HTTP,
and it processes the request, generates dynamic content, and returns the response to the client.
Example:
@WebServlet("/HelloServlet")
public class HelloServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws
ServletException, IOException {
response.getWriter().println("Hello, World!");
}
}
While Java Servlets are powerful tools for creating dynamic web applications, there are other
server-side technologies such as PHP, ASP.NET, and Ruby on Rails. Let’s compare some
key differences:
Performance: Java Servlets are more scalable and perform better under heavy traffic
compared to PHP and other scripting technologies.
Language: Servlets are written in Java, a statically typed language, whereas PHP,
Ruby, and ASP.NET use dynamically typed languages.
Integration: Java Servlets integrate seamlessly with other Java-based technologies
such as JDBC for database connectivity, while PHP integrates well with MySQL.
Concurrency: Servlets are better equipped for handling multiple requests concurrently
due to their multi-threaded nature.
LIFECYCLE OF A SERVLET
The lifecycle of a servlet is controlled by the Servlet Container (also known as the web
container). It defines how the servlet is loaded, initialized, serviced, and destroyed. There are
four main stages in the lifecycle:
1. Loading and Instantiation: The servlet is loaded when the first request is made.
2. Initialization: The init() method is called once after the servlet is instantiated.
3. Request Handling: The service() method processes client requests. This method is
called multiple times, once for each request.
4. Destruction: The destroy() method is invoked when the servlet is removed from
service, usually when the server shuts down.
Example:
Servlets use several key interfaces and classes. Here are the core components:
1. HttpServlet: The base class for handling HTTP requests. It simplifies handling HTTP-
specific operations.
2. HttpServletRequest: Represents the request from the client, containing all the
information like parameters, headers, and cookies.
3. HttpServletResponse: Represents the response sent to the client, including data such
as the status code, headers, and content.
4. ServletConfig: Contains initialization parameters for the servlet.
Servlets handle requests and responses through the HttpServletRequest and HttpServletResponse
objects. The doGet() and doPost() methods are used to handle HTTP GET and POST requests,
respectively.
@WebServlet("/RequestHandler")
public class RequestHandlerServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws
ServletException, IOException {
String name = request.getParameter("name");
response.getWriter().println("Hello, " + name);
}
}
1. Using Annotations:
@WebServlet("/HelloWorld")
public class HelloWorldServlet extends HttpServlet {
// Servlet code here
}
xml
<servlet>
<servlet-name>HelloWorldServlet</servlet-name>
<servlet-class>com.example.HelloWorldServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloWorldServlet</servlet-name>
<url-pattern>/HelloWorld</url-pattern>
</servlet-mapping>
1. Filters: Filters are used to modify request and response objects, such as logging,
authentication, or modifying content before sending it to the client.
2. Listeners: Listeners are objects that listen to events in a web application (such as
session creation or destruction) and respond accordingly.
Example:
JSP vs Servlets
JSP is primarily used for presenting data (view layer) and generating dynamic content
using HTML and Java.
Servlets are used for handling business logic (controller layer) and managing HTTP
requests/responses.
JSP offers a simpler syntax, whereas Servlets require more lines of code to generate the same
output.
1. Directives: Provide configuration information to the JSP container. They appear at the
top of the page.
<%@ page language="java" contentType="text/html" %>
<%
int count = 1;
out.println("Count: " + count);
%>
EL simplifies the interaction between JSP and Java objects by providing an easy way to access
JavaBeans properties and expressions.
Example:
${user.name}
EL automatically resolves the value of user.name from a JavaBean.
Servlets handle the Controller logic, processing the request and forwarding it to the
Custom tags in JSP allow you to define reusable components and extend JSP’s functionality.
You can create your own tags for specific actions, which makes the code cleaner and more
modular.
The frontend represents what the user sees and interacts with. In your case, it's the
HTML/CSS page that handles the structure and appearance of the Admin Page.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Admin Page</title>
<style>
/* Styling for header, navigation, etc. */
/* Flexbox Layout and responsiveness */
/* ... */
</style>
</head>
<body>
<header class="header">
<h1 class="logo">Logo</h1>
<div class="admin-header">
<span>Admin</span>
</div>
<ul class="nav">
<li><a href="Adminuploadfile.jsp">Upload Data</a></li>
<li><a href="#">Employee Status</a></li>
<li><a href="#">Industry Data</a></li>
<li><a href="#">Testing Analysis</a></li>
<li><a href="#">Pasting</a></li>
<li><a href="#">Download Data</a></li>
<li><a href="#">Logout</a></li>
</ul>
</header>
</body>
</html>
Responsiveness: You used Flexbox layout to make the page responsive. Good for
different screen sizes.
Navigation Links: You have links such as "Upload Data", "Employee Status", etc.,
which are important for the admin interface.
Styling: The page has custom styles for the header and navigation to make it visually
appealing.
2. Business Layer (Servlet Layer)
The business layer contains logic that processes the requests and handles communication
between the frontend and the backend (database).
package Adminpage;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/login")
public class login extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws
ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
// Simple logic to authenticate and redirect to the admin homepage.
// In a real-world application, you would check the credentials from the database.
response.sendRedirect("adminhomepage.html");
}
}
Login Authentication: In this example, the login servlet captures the username and
password from the request and performs some authentication logic.
o Improvement: Implement real authentication using a database to check user
credentials instead of just redirecting.
3. DATABASE LAYER
The database layer handles the connection to the database, providing methods to retrieve or
insert data.
java
Copy code
package dbconnection;
import java.sql.Connection;
import java.sql.DriverManager;
To improve organization and scalability, you can structure the application using the Model-
Model (Database Layer): Represents data and the logic for interacting with the
database.
o Dbconn.java
o User.java (For user-related actions in the database)
View (Frontend): Contains all the HTML/JSP pages and frontend logic.
o adminPage.jsp
o login.jsp
o adminhomepage.jsp
Controller (Servlet Layer): Handles user requests and communicates with the
Model.
o LoginServlet.java
o AdminDataServlet.java (for handling admin data requests)
Example for Handling the Business Layer (Login Validation)
You can improve the login servlet by validating the credentials from the database. Here's an
updated example:
LOGINSERVLET.JAVA
package Adminpage;
import dbconnection.Dbconn;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws
ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
Connection conn = Dbconn.getconnection();
try {
// Prepare SQL query to validate login credentials
String query = "SELECT * FROM users WHERE username = ? AND password = ?";
PreparedStatement pst = conn.prepareStatement(query);
pst.setString(1, username);
pst.setString(2, password);
ResultSet rs = pst.executeQuery();
if (rs.next()) {
// Successful login, redirect to admin homepage
response.sendRedirect("adminhomepage.jsp");
} else {
// Invalid login, redirect to login page with error
response.sendRedirect("login.jsp?error=invalid");
}
} catch (Exception e) {
e.printStackTrace();
}
}}
Database Query: This updated servlet checks if the username and password match
any record in the users table.
Error Handling: Redirects back to the login page if authentication fails with an error
message.
A web application is software that runs on web browsers and is accessible over the
internet.
It provides a graphical user interface (GUI) for users to interact with and performs
various business and data management tasks.
Integration-Friendly: Works with popular tools like Hibernate, Quartz, and JEE.
Java 1.0 was launched in 1995, laying the foundation for Java-based web development.
The Servlet API 1.0 was introduced in 1997, enabling dynamic web applications.
Early Java web applications were primarily built using Servlets and Java Server Pages
(JSP).
Servlets:
Servlets are Java classes that run on a web server, handling HTTP requests and
generating responses.
They extend web server capabilities, enabling tasks such as:
JSP allows the seamless combination of HTML and Java code in a single file.
At runtime, JSP files are compiled into servlets, making them an efficient tool for
generating dynamic content.
Key uses of JSP include:
The Apache Struts 1.0 framework debuted in 2000, providing a structured approach to
web application development.
The Spring Framework 1.0, launched in 2004, introduced simpler methods for creating
robust web applications.
The rise of Asynchronous JavaScript and XML (Ajax) enabled dynamic, interactive
web applications.
Rich Internet Applications (RIAs) became widely popular.
Java Server Faces (JSF), a component-based web framework, was introduced to
streamline UI development.
Java EE 6 continued this trend, offering enhanced tools for creating scalable
applications.
This evolution highlights Java’s versatility and enduring relevance in web development.
SPRING BOOT
Spring Boot is an open-source Java framework designed to simplify the development and
deployment of Java applications.
Built by the Pivotal Team, it enables Rapid Application Development (RAD) with
minimal configuration.
It combines the Spring Framework with embedded servers, eliminating the need for
extensive XML configuration.
This tutorial is ideal for beginners and professionals, covering basic to advanced topics
such as REST APIs, Micro services, Kafka, and Data JPA integration.
PRESENTATION LAYER
Role: Responsible for the user interface (UI) and user interaction.
Technologies:
Modern Additions:
Web Components: Reusable custom HTML elements encapsulating
functionality.
Progressive Web Apps (PWAs): Provide offline capabilities, faster load times,
and native app-like features.
Example:
A modern Spring Boot application often uses React for the front-end.
A simple React component can look like this:
Role: Manages application logic, processes requests, and connects the front-end with the
database.
Technologies:
Approaches:
@RestController
@RequestMapping("/api")
this.userService = userService;
@GetMapping("/users/{id}")
return ResponseEntity.ok(userService.findById(id));
} }
Role: Handles data persistence and retrieval using relational or non-relational databases.
Technologies:
Modern Additions:
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
BEAN :
In Spring Boot, a bean is an object that is managed by the Spring IoC (Inversion
of Control) container.
Beans are the backbone of a Spring-based application, and they represent a
reusable component or a service that can be used throughout the application.
Concept: Delegates object creation and lifecycle management to the Spring IoC
container.
@Component
}
}
@Service
@Autowired
this.notificationService = notificationService;
Spring Boot provides powerful dependency injection features using its Spring Framework.
Constructor Injection,
Setter Injection
Field Injection.
1. Constructor Injection:
This is the recommended approach for DI in Spring, especially for mandatory dependencies.
Example:
Service Class (Dependency):
package com.example.demo.service;
import org.springframework.stereotype.Service;
@Service
System.out.println("Engine started!");
@Service Annotation
The @Service annotation indicates that the class is a service component in the Spring
application.
Role of @Service:
Dependent Class:
package com.example.demo.car;
import com.example.demo.service.EngineService;
import org.springframework.stereotype.Component;
@Component
// Constructor Injection
this.engineService = engineService;
engineService.startEngine();
System.out.println("Car is driving...");
}
@Component Annotation
During component scanning, Spring identifies this class and registers it as a bean in the
Application Context.
This makes the Car object available for dependency injection wherever needed.
Main Application:
package com.example.demo;
import com.example.demo.car.Car;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@Autowired
this.car = car;
}
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
@Override
car.drive();
Car is driving..
Constructor Injection:
Mandatory Dependencies: Ensures that the Car class cannot be instantiated without
providing the required EngineService dependency.
This approach is used for optional dependencies. one of the ways to inject dependencies
into a class.
In this approach, Spring uses the setter methods of a class to inject dependencies after the
object is created.
Setter injection allows for more flexibility as it allows the injection of dependencies after
the object’s construction, unlike constructor injection which is required during object
creation.
Example:
package com.example.demo.service;
import org.springframework.stereotype.Service;
@Service
System.out.println("Engine started!"); }}
Dependent Class:
package com.example.demo.car;
import com.example.demo.service.EngineService;
import org.springframework.stereotype.Component;
@Component
// Setter Injection
@Autowired
this.engineService = engineService;
if (engineService != null) {
engineService.startEngine();
System.out.println("Car is driving...");
} else {
Main Application:
package com.example.demo;
import com.example.demo.car.Car;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.SpringApplication;
@SpringBootApplication
@Autowired
SpringApplication.run(DemoApplication.class, args);
@Override
car.drive();
Output:
Engine started!
Car is driving...
3. FIELD INJECTION:
package com.example.demo.service;
import org.springframework.stereotype.Service;
@Service
System.out.println("Engine started!");
Dependent Class:
package com.example.demo.car;
import com.example.demo.service.EngineService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
@Autowired
System.out.println("Car is driving...");
}}
Main Application:
package com.example.demo;
import com.example.demo.car.Car;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.SpringApplication;
@SpringBootApplication
@Autowired
SpringApplication.run(DemoApplication.class, args);
@Override
car.drive();
Output:
Engine started!
Car is driving...
Summary of Usage
In Spring Boot, POJO classes are commonly used as data carriers or domain objects,
which represent and hold data throughout different layers of the application.
These classes work seamlessly with Spring Boot due to its design principles like
dependency injection, loose coupling, and data-binding.
Entity Representation:
POJOs are used to represent entities in database operations, typically annotated with
JPA/Hibernate annotations like @Entity.
POJOs can serve as DTOs to transfer data between layers like controllers, services, and
repositories.
POJOs represent the body of HTTP requests and responses in REST APIs.
Dependency Injection:
Spring Boot uses POJOs as services or components, injecting them where needed.
Below is a list of commonly used Spring Boot annotations, their purposes, and additional
annotations for advanced use cases.
CORE ANNOTATIONS :
@SpringBootApplication:
container.
@Qualifier: Specifies which bean to inject when multiple beans of the same type exist.
@Primary Marks a bean as the primary candidate for injection when multiple beans
Web Annotations :
2. Create Repository
When used with JPA, POJO classes are annotated as entities, enabling ORM (Object Relational
Mapping)
Example:
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
@Entity
@Id
public User() {}
this.id = id;
this.name = name;
HOW IT WORKS:
Fields are mapped to columns, and Spring Boot uses this POJO for CRUD operations
through Jpa Repository.
Java Persistence API is a collection of classes and methods to persistently store the vast
amounts of data into a database which is provided by the Oracle Corporation.
JPA is a specification which specifies how to access, manage and persist information/data
between java objects and relational databases
It provides a standard approach for ORM, Object Relational Mapping. Spring Boot
provides a seemless integration with JPA.
Method Description
Method Description
findAll(Pageable
Retrieves a paginated list of entities.
pageable)
QUERY EXECUTION:
Method Description
Example:
REST API :
Stateless: Each request contains all information needed; the server does not store session
data.
Resource-Oriented: Everything (like a user, product, etc.) is treated as a resource with
unique URIs.
HTTP Status Codes: Provides responses like 200 OK, 404 Not Found, and 201 Created.
In Spring Boot, REST APIs are built using controllers with annotations like:
@RestController:
@RequestMapping:
1. @PathVariable
Purpose: Extracts values from the URI path.
Example:
@GetMapping("/users/{id}")
return userService.getUserById(id);
2. @RequestBody
Use Case: For sending JSON or XML data in POST or PUT requests.
Example:
@PostMapping("/users")
return userService.createUser(user);
3. @RequestParam
Example:
@GetMapping("/users")
return userService.getUsersByRole(role);
4. @RequestHeader
Example:
@GetMapping("/secure-data")
return securityService.validateToken(token);
5. @ResponseBody
Purpose: Converts Java objects into HTTP response body (usually JSON or XML).
Use Case: Automatically added when using @RestController.
Example:
@GetMapping("/users/{id}")
@ResponseBody
return userService.getUserById(id);
6. @RequestMapping
Purpose: Maps a URL to a controller or its methods. Can handle multiple HTTP methods.
Use Case: For basic mappings or when using method-specific annotations like
@GetMapping.
Example:
return userService.getAllUsers();
7. @ResponseStatus
Example:
@DeleteMapping("/users/{id}")
@ResponseStatus(HttpStatus.NO_CONTENT)
8. @CrossOrigin
Example:
@CrossOrigin(origins = "http://example.com")
@GetMapping("/users")
return userService.getAllUsers();
9. @Valid
Purpose: Validates request bodies based on constraints defined in the entity class.
Use Case: For automatic validation of inputs.
Example:
@PostMapping("/users")
return userService.createUser(user);
10. @ExceptionHandler
Purpose: Handles specific exceptions globally or for a specific controller.
Use Case: To return custom error responses.
Example:
@ExceptionHandler(UserNotFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
return ex.getMessage();
These annotations make building REST APIs in Spring Boot more efficient by managing request
and response data effortlessly!