0% found this document useful (0 votes)
17 views175 pages

Java Programming Notes-3

Java, developed by James Gosling at Sun Microsystems in 1991, has evolved through various milestones, including its open-source transition in 2006 and acquisition by Oracle in 2010. It is characterized by features such as platform independence, object-oriented design, and robust security, making it suitable for diverse applications from desktop to enterprise-level systems. Java's ecosystem includes multiple editions like Java SE, EE, ME, and JavaFX, each tailored for specific use cases, and is maintained primarily by Oracle alongside contributions from the OpenJDK community.

Uploaded by

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

Java Programming Notes-3

Java, developed by James Gosling at Sun Microsystems in 1991, has evolved through various milestones, including its open-source transition in 2006 and acquisition by Oracle in 2010. It is characterized by features such as platform independence, object-oriented design, and robust security, making it suitable for diverse applications from desktop to enterprise-level systems. Java's ecosystem includes multiple editions like Java SE, EE, ME, and JavaFX, each tailored for specific use cases, and is maintained primarily by Oracle alongside contributions from the OpenJDK community.

Uploaded by

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

Java Evolution and Overview of Java Language

1. Java History

Java was developed by James Gosling and his team, known as the Green Team, at Sun Microsystems
in 1991. The project was initially called "Oak", named after an oak tree outside Gosling's office. Later,
it was renamed Java, inspired by Java coffee from Indonesia.

Key Milestones:

• 1991: Project started as Oak for embedded systems.

• 1995: Officially renamed Java; released publicly with Java 1.0.

• 1999: Java 2 (J2SE) introduced with significant improvements.

• 2006: Java became open-source under the GNU General Public License.

• 2010: Oracle Corporation acquired Sun Microsystems and took over Java development.

• 2017 - Present: Introduction of Java SE 9+ with new features like modularity, JShell, and
regular feature releases.

• As of February 4, 2025, the latest release of the Java Standard Edition (SE) platform is Java SE
23, which was released on September 17, 2024.

2. Features of Java

Java is designed to be simple, robust, secure, and platform-independent. Key features include:

1. Platform Independence: "Write Once, Run Anywhere" (WORA). Java code runs on any device
with a Java Virtual Machine (JVM).

2. Object-Oriented: Everything in Java is treated as objects, promoting code reusability and


modularity.

3. Simple and Easy to Learn: Its syntax is clean, derived from C++, but with simplified features.

4. Secure: Built-in security features, including runtime security checks and advanced
authentication.

5. Robust: Strong memory management, exception handling, and garbage collection.

6. Architecture-Neutral: Java bytecode can run on any hardware with a compatible JVM.

7. High Performance: Although slower than C/C++, Java’s Just-In-Time (JIT) compiler improves
execution speed.

8. Multithreaded: Supports multithreading for concurrent programming.

9. Distributed: Built-in networking libraries make Java suitable for distributed systems.

10. Dynamic: Java supports dynamic linking and loading of classes during runtime.
3. How Java is Different from C and C++

Aspect C C++ Java


Paradigm Procedural Object-Oriented & Pure Object-Oriented
Procedural (mostly)
Memory Manual (pointers) Manual Automatic (Garbage
Mgmt Collection)
Platform Platform-dependent Platform-dependent Platform-independent (via
JVM)
Pointers Supported Supported Not supported (for security)
Multiple Not supported Supported (with Achieved via interfaces
Inheritance complexity)
Security Less secure More secure than C Highly secure
Compilation Compiled to machine Compiled to machine Compiled to bytecode (runs
code code on JVM)
Operator Not supported Supported Not supported
Overloading
Performance High performance High performance Slightly lower but optimized
via JIT

4. Java and the World Wide Web (WWW)

Java revolutionized web development with features suited for the Internet:

• Applets: Small Java programs embedded in web pages (now deprecated due to security
issues).

• Servlets and JSP: Server-side technologies for dynamic web content.

• Platform Independence: Java applications run on any system with a JVM, making it ideal for
distributed web applications.

• Security: Java’s sandbox model for applets provided secure web execution (in earlier web
applications).

• Java APIs: Extensive APIs support networking, XML parsing, database access, and web
services.

5. Java Web Browser

HotJava was the first web browser written entirely in Java. It demonstrated Java’s capabilities,
especially running applets.

Key Points:

• Dynamic Content: Could run Java applets within web pages.

• Platform Independent: Worked across platforms without modification.


• Legacy: While modern browsers phased out Java applets, Java technologies like Servlets, JSP,
and Spring Boot continue to power web applications.

6. Java Environment

The Java environment consists of several components required for developing and running Java
applications.

6.1 Java Development Kit (JDK)

The JDK is a software development environment for building Java applications. It includes:

• Java Compiler (javac): Converts Java source code into bytecode.

• Java Runtime Environment (JRE): Required to run Java applications, includes JVM, core
libraries, and other components.

• Java Virtual Machine (JVM): Executes the compiled bytecode on any device.

• Development Tools: Debugger, documentation generator, and other utilities.

JDK Components:

1. javac: Compiler to convert .java files to .class bytecode files.

2. java: Launcher to execute Java applications.

3. javadoc: Tool to generate API documentation.

4. jar: Tool to package Java classes into JAR files.

5. jdb: Java debugger.

6.2 Java Runtime Environment (JRE)

The JRE is part of the JDK, necessary for running Java programs. It includes:

• JVM: Executes bytecode.

• Class Libraries: Provides standard functionalities.


• Other Files: Configuration files, resources, etc.

6.3 Java Virtual Machine (JVM)

The JVM is a virtual engine that enables Java’s platform independence.

• Class Loader: Loads .class files into memory.

• Bytecode Verifier: Checks code for security violations.

• Interpreter/JIT Compiler: Executes bytecode instructions.

6.4. Java Just-In-Time (JIT) Compiler

The Just-In-Time (JIT) Compiler is a crucial part of the Java Virtual Machine (JVM) that significantly
improves the performance of Java applications by compiling bytecode into native machine code at
runtime.

• The JIT Compiler is part of the JVM that translates Java bytecode (platform-independent
code) into native machine code just before execution.

• This process happens "just in time" to run the program efficiently, hence the name.

• By converting bytecode to machine code, the JIT allows Java programs to run faster because
the CPU can execute native code directly without further interpretation.

2. How Does the JIT Compiler Work?

1. Java Source Code → Compiled by javac → Bytecode (.class files)

2. Bytecode Loaded into JVM → Initially interpreted by the JVM's interpreter

3. JIT Compiler Activation:

o As the program runs, the JVM monitors the code.

o Hotspot Detection: Frequently executed code (called "hot spots") is identified.

o Compilation: The JIT compiles these hot spots into native machine code.

4. Execution: Native code runs directly on the hardware for faster performance.

7. Java Program Lifecycle

1. Write Code: Save as Program.java.

2. Compile Code: javac Program.java → generates Program.class.

3. Run Program: java Program → JVM executes the bytecode.


Java Program Execution Flow

1. Write Code (Source Code)

• Tool: Text Editor (VS Code, IntelliJ, Notepad, etc.)

• File Extension: .java

• Example: HelloWorld.java

public class HelloWorld {

public static void main(String[] args) {

System.out.println("Hello, World!");

2. Compile Code (Java Compiler - javac)

• Command: javac HelloWorld.java

• Purpose: Converts Java Source Code into Bytecode (platform-independent).

• Output: .class file (e.g., HelloWorld.class)

3. Bytecode (.class File)

• What is Bytecode?
A set of intermediate instructions that can run on any device with a JVM.

• Platform Independence: This makes Java “Write Once, Run Anywhere.”

4. Load into JVM (Class Loader Subsystem)

• Role: Loads .class files into the Java Virtual Machine.


• Types of Class Loaders:

o Bootstrap ClassLoader (loads core Java classes)

o Extension ClassLoader (loads JDK extension libraries)

o Application ClassLoader (loads user-defined classes)

5. Bytecode Verification (Bytecode Verifier)

• Purpose: Ensures bytecode is safe, secure, and doesn’t violate Java rules.

• Checks for:

o Stack overflows

o Illegal memory access

o Security violations

6. Execution Engine

The heart of the JVM where the actual execution happens.

• Interpreter:

o Reads and executes bytecode line-by-line.

o Fast for small programs but slower for large loops.

• JIT (Just-In-Time) Compiler:

o Detects frequently used code (hotspots) and converts them to native machine code.

o Boosts performance significantly.

o Uses techniques like inlining and loop unrolling for optimization.

7. Native Machine Code

• Generated by: JIT Compiler

• Runs on: The underlying operating system and hardware directly

• Result: Faster execution speed after initial interpretation

8️. Program Output

• The final result is displayed on the console or GUI.

• Example Output:

Hello, World!
Java SE, EE, ME and Other Related Terms
Java is a versatile programming language with different editions tailored for various applications.
Here’s an overview of the key Java editions:

1. Java SE (Standard Edition)

Java SE (Standard Edition) provides the core functionality for developing general-purpose desktop,
server, and embedded device applications.

Key Features:

• Core Java libraries (java.lang, java.util, java.io, etc.)

• Basic APIs for data structures, networking, database connectivity (JDBC), multithreading, etc.

• Development tools like JDK (Java Development Kit), JRE (Java Runtime Environment), and
JVM (Java Virtual Machine).

Use Cases:

• Desktop applications

• Console-based applications

• Core libraries for other Java editions

2. Java EE (Enterprise Edition)

Java EE (Enterprise Edition), now renamed as Jakarta EE, is built on top of Java SE and designed for
large-scale, distributed, enterprise-level applications.

Key Features:

• Servlets, JSP (JavaServer Pages): For dynamic web content

• Enterprise JavaBeans (EJB): For building robust, scalable enterprise applications

• JPA (Java Persistence API): For database access

• Web Services (REST, SOAP): For API-based communication

• Dependency Injection, Security, and Transactions

Use Cases:

• Enterprise applications

• Web applications

• Microservices architecture

• Distributed systems
3. Java ME (Micro Edition)

Java ME (Micro Edition) is designed for resource-constrained devices like embedded systems, mobile
phones, IoT devices, etc.

Key Features:

• Lightweight APIs tailored for small devices

• Optimized JVM for embedded environments

• Device-specific configurations (CLDC, CDC)

Use Cases:

• Smart cards

• Set-top boxes

• IoT devices

• Legacy mobile applications (before Android's dominance)

4. JavaFX

JavaFX is a platform for building rich, modern user interfaces in desktop applications. It offers
advanced graphics, media functionalities, and UI controls.

Key Features:

• Declarative UI using FXML

• CSS styling support

• 2D and 3D graphics APIs

• Integration with web content

Use Cases:

• Desktop applications with rich UIs

• Data visualization tools

• Media applications

5. Java Card

Java Card technology enables Java applications (applets) to run securely on smart cards and
embedded devices with limited memory.

Key Features:

• High security for sensitive data

• Lightweight Java Virtual Machine (JVM)


• Optimized for secure transactions

Use Cases:

• Smart cards for banking

• SIM cards

• Secure ID cards

6. Related Java Terms

• JDK (Java Development Kit): A software development kit for Java applications, including
tools like javac (compiler), java (runtime), etc.

• JRE (Java Runtime Environment): Provides libraries and JVM to run Java applications.

• JVM (Java Virtual Machine): Executes Java bytecode, making Java platform-independent.

• JCP (Java Community Process): Governing body for Java standards and specifications.

• JAR (Java Archive): A file format to package Java classes and resources.

• JIT (Just-In-Time Compiler): Optimizes Java bytecode into machine code at runtime for faster
execution.

Comparison of Java Editions

Aspect Java SE Java EE (Jakarta Java ME JavaFX


EE)
Purpose General-purpose Enterprise Embedded & Rich desktop UIs
development applications mobile devices
APIs Core APIs Web services, EJB, Lightweight APIs UI Controls,
(Collections, I/O) Servlets Graphics
Deployment Desktop, server, Web servers, IoT devices, smart Desktop
embedded cloud cards applications
Complexity Moderate High (enterprise- Low (optimized for Moderate (UI
level) devices) design focus)

Java Edition Free to Use? Notes

Java SE (Standard Yes (OpenJDK) Paid OpenJDK is free, Oracle JDK is subscription-
Edition) (Oracle JDK for business use) based for commercial use.
Java EE Yes Open-source and free for enterprise use.
(Enterprise/Jakarta
EE)
Java ME (Micro Mostly free Some commercial implementations may
Edition) require a license.
JavaFX Yes Fully open-source under OpenJFX.
Conclusion

Java’s ecosystem is broad, supporting development for everything from mobile devices to enterprise
servers.

• Java SE is foundational for all Java development.

• Java EE (Jakarta EE) caters to enterprise-grade, scalable applications.

• Java ME serves embedded and mobile environments.

• JavaFX is specialized for building sophisticated GUI-based applications.

Who Maintains Java Today?

Java is maintained by multiple organizations, with Oracle Corporation playing the primary role,
alongside contributions from the OpenJDK Community and other tech companies. Here's a
breakdown:

1. Oracle Corporation (Primary Maintainer)

• Role: Oracle is the official steward of Java, responsible for releasing the official Java
Development Kit (JDK), setting standards, and managing Java SE (Standard Edition).

• Key Contributions:

o Maintains Oracle JDK (commercial version)

o Oversees Java's development through the Java Community Process (JCP)

o Provides security updates, bug fixes, and feature enhancements

2. OpenJDK Community (Open-Source Maintainer)

• Role: OpenJDK (Open Java Development Kit) is the open-source reference implementation
of Java. It’s where most new Java features are first developed.

• Contributors: Oracle, Red Hat, Amazon, IBM, Microsoft, Azul Systems, and individual
developers.

• Key Distributions:

o Temurin (by Adoptium)

o Amazon Corretto

o Zulu (by Azul Systems)

o Red Hat OpenJDK

3. Java Community Process (JCP)


• Role: A formal organization that defines Java standards through Java Specification Requests
(JSRs).

• Members: Oracle, IBM, Red Hat, SAP, Google, Microsoft, and other industry leaders.

• Purpose: Approves new Java features, APIs, and platform changes.

4. Eclipse Foundation (Maintainer of Jakarta EE)

• Role: After Oracle donated Java EE, it was renamed Jakarta EE and is now maintained by the
Eclipse Foundation.

• Contributors: IBM, Red Hat, Payara, Tomitribe, etc.

5. Major Tech Companies Involved in Java Development

• Red Hat: Maintains OpenJDK distributions, especially for enterprise Linux systems.

• Amazon: Develops Amazon Corretto, a free, production-ready OpenJDK distribution.

• Microsoft: Actively contributes to OpenJDK and integrates Java into its Azure cloud platform.

• Google: Uses Java for Android development (though with its own set of APIs).

Summary:

Organization Role in Java Maintenance


Oracle Corporation Primary maintainer of Java SE, Oracle JDK, security updates
OpenJDK Community Open-source development and reference implementation
Java Community Process (JCP) Defines Java standards and approves new features
Eclipse Foundation Maintains Jakarta EE (formerly Java EE)
Red Hat, Amazon, Microsoft Major contributors to OpenJDK and enterprise Java solutions

Who Controls Java?

• Java is controlled by Oracle (for the official JDK and trademarks).

• Java’s development is open and collaborative through the OpenJDK and JCP.

• Enterprise Java (Jakarta EE) is governed by the Eclipse Foundation.

JSP vs Servlets: A Detailed Comparison

When building Java-based web applications, JSP (JavaServer Pages) and Servlets are two key
technologies. Both serve the purpose of creating dynamic web content, but they differ in their
approach, usage, and underlying mechanisms.

1. What Are Servlets?


A Servlet is a Java class that runs on a Java-enabled web server (like Apache Tomcat) to handle HTTP
requests and generate dynamic responses.

Key Features:

• Written entirely in Java

• Handles business logic and request-processing tasks

• Uses HttpServlet class for HTTP-specific functionalities

• Requires manual HTML generation using PrintWriter

Simple Servlet Example:


import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class HelloServlet extends HttpServlet {


public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<h1>Hello from Servlet!</h1>");
}
}

2. What Is JSP (JavaServer Pages)?

JSP is a server-side technology that allows embedding Java code directly within HTML pages. It
simplifies web development by separating the presentation layer from business logic.

Key Features:

• Primarily used for presentation (UI/HTML generation)

• Java code is written within special tags like <% %>

• Compiled into Servlets internally by the server

• Easier to maintain for pages with lots of HTML content

Simple JSP Example:


<%@ page language="java" contentType="text/html" %>
<html>
<body>
<h1>Hello from JSP!</h1>
<%
out.println("This is dynamic content generated by Java
code.");
%>
</body>
</html>

3. Key Differences Between JSP and Servlets

Aspect Servlets JSP (JavaServer Pages)


Nature Pure Java code HTML with embedded Java code
Primary Use Business logic, request handling Presentation layer (UI), dynamic content
generation
Compilation Written and compiled as Java Compiled into Servlets internally by the
classes server
Syntax Complexity Requires complex syntax for Simplifies web page development with
HTML generation easy HTML integration
Performance Slightly faster (direct Java code Slightly slower (compiled into Servlets
execution) first)
Maintainability Hard to maintain with lots of Easier to maintain for UI changes
HTML code
Separation of Less separation of UI and Better separation using MVC
Concerns business logic architecture
Lifecycle Controlled via init(), service(), Handled by the JSP engine (converted to
destroy() methods Servlets)
Use Cases APIs, backend logic, REST Web pages, dynamic forms, content
services rendering

4. How JSP and Servlets Work Together (MVC Pattern)

In modern Java web development, Servlets and JSPs are often used together in the Model-View-
Controller (MVC) architecture:

• Model: Business logic (Java classes, databases)

• Controller: Servlets handle client requests, process data, and forward results

• View: JSP files display the processed data in a user-friendly format

Example Workflow:

1. Client Request → Sent to a Servlet (Controller).

2. Servlet → Processes the request, interacts with the database (Model).

3. Forward → Passes the data to a JSP (View) for rendering.


4. Response → JSP generates the final HTML and sends it back to the browser.

5. When to Use JSP or Servlets?

• Use Servlets When:

o Handling form submissions

o Processing HTTP requests/responses

o Implementing APIs, RESTful services, or backend logic

• Use JSP When:

o Displaying dynamic data (HTML pages)

o Designing UI with embedded Java code

o Building web forms, dashboards, and reports

Final Verdict:

• Servlets = Best for backend logic and request processing.

• JSP = Best for UI presentation and dynamic web pages.


Java Programming Basics: Tokens, Constants,
Variables, Expressions, Control Statements, and Loops

1. Java Programming Structure

A typical Java program consists of the following components:

Structure of a Java Program:


// Package Declaration (optional)
package mypackage;
// Import Statements
import java.util.Scanner;
// Class Declaration
public class HelloWorld {
// Main Method - Entry Point of the Program
public static void main(String[] args) {
// Variable Declaration
String message = "Hello, World!";
// Output Statement
System.out.println(message);
}
}

Key Components:

1. Package Declaration: Organizes classes into namespaces.

2. Import Statements: Imports built-in or user-defined classes.

3. Class Declaration: Java is object-oriented, so every program is part of a class.

4. Main Method (main()): Starting point of any Java application.

5. Statements: Instructions to perform specific actions.

6. Comments: Single-line (//) or multi-line (/* ... */) notes ignored by the compiler.

1. Package Declaration (Optional)


package mypackage;
• package: A keyword in Java used to organize classes into namespaces. It helps manage large
projects by grouping related classes together.

• mypackage: The name of the package. You can choose any valid name.

• ; (Semicolon): Marks the end of the statement.

Note: This line is optional. If omitted, the class belongs to the default package.

2. Import Statement

import java.util.Scanner;

• import: A keyword used to bring other Java classes or packages into the current file, allowing
us to use them without writing the full path.

• java.util.Scanner: Refers to the Scanner class from the java.util package. This class is used to
take input from the user.

• ;: Ends the import statement.

Note: In this program, Scanner isn’t used, but in real-world programs, it's helpful for user input.

3. Class Declaration

public class HelloWorld {

• public: An access modifier that makes the class accessible from other classes.

• class: A keyword used to define a class in Java. A class is a blueprint for creating objects.

• HelloWorld: The name of the class. It should match the filename (i.e., HelloWorld.java).

• { (Opening Curly Brace): Marks the start of the class body, where you write the code inside.

4. Main Method - Entry Point

public static void main(String[] args) {

This is the entry point of every Java application. The JVM (Java Virtual Machine) starts executing the
program from this method.

• public: The method is accessible from outside the class (required by JVM to execute it).

• static: Means this method belongs to the class and can be run without creating an object.

• void: Specifies that this method doesn’t return any value.

• main: The name of the method. This is predefined in Java; changing it will cause errors.

• (String[] args):

o String[]: Declares an array of String objects.


o args: The variable name that holds command-line arguments when the program is
run from the terminal.

• {: Starts the body of the main method.

5. Variable Declaration

String message = "Hello, World!";

• String: A data type in Java used to store text (sequence of characters).

• message: The name of the variable that will store the text.

• = (Assignment Operator): Assigns the value on the right to the variable on the left.

• "Hello, World!": A string literal representing the actual text we want to display.

• ;: Ends the statement.

6. Output Statement

System.out.println(message);

This line prints the value of message to the console.

• System: A predefined class in Java that provides access to system-related resources.

• . (Dot Operator): Used to access members (methods or variables) of a class.

• out: A static member of the System class, representing the standard output stream (the
console).

• println: A method of out that prints the specified content to the console, followed by a new
line.

• (message): The argument passed to println. Here, it refers to the message variable, which
contains "Hello, World!".

• ;: Ends the statement.

7. Closing Braces

• } (Closing Curly Brace): Closes the main method and then the class HelloWorld.

Complete Flow of Execution:

1. JVM starts the program from the main() method.


2. The string "Hello, World!" is stored in the variable message.

3. The System.out.println() method prints the value of message to the console.

4. The program ends after executing the last statement.

Final Output:

Hello, World!

2. Java Tokens

Tokens are the smallest units in a Java program.

Types of Tokens:

1. Keywords: Reserved words with special meaning.


Examples: int, class, public, static, void, if, else, while, return, import, etc.

2. Identifiers: Names given to variables, classes, methods, etc.


Example: myVariable, calculateSum, EmployeeDetails

3. Literals (Constants): Fixed values assigned to variables.


Example: 100, 'A', 3.14, "Hello"

4. Operators: Symbols for operations like arithmetic, logical, relational.


Example: +, -, *, /, &&, ==

5. Separators (Delimiters): Symbols to separate code components.


Example: (), {}, [], ;, ,

6. Comments:

o Single-line: // This is a comment

o Multi-line: /* This is a multi-line comment */

Java Tokens
A token in Java is the smallest unit of a Java program that the compiler recognizes. Tokens are like
the building blocks of Java code. When we write a Java program, the compiler breaks it down into
tokens during the lexical analysis phase of compilation.

Types of Java Tokens:

1. Keywords

2. Identifiers

3. Literals (Constants)
4. Operators

5. Separators (Punctuators)

6. Comments

1. Keywords

• Keywords are reserved words in Java that have a specific meaning and purpose.

• They cannot be used as variable names, class names, or method names.

• Java is case-sensitive, so class is a keyword, but Class is not.

Examples:
class, public, static, void, int, if, else, while, return, new, try, catch, etc.

2. Identifiers

• Identifiers are the names we give to variables, classes, methods, objects, arrays, etc.

• They help us refer to these program elements in our code.

Rules for Valid Identifiers in Java:

1. Allowed Characters:

o Letters (A–Z, a–z), digits (0–9), underscore (_), and dollar sign ($).

2. Cannot Start with a Digit:

o Example: 1variable is invalid, but variable1 is valid.

3. No Reserved Keywords:

o Cannot use Java keywords like int, class, public as identifiers.

4. Case-Sensitive:

o Variable and variable are different identifiers in Java.

5. No Spaces:

o Identifiers cannot contain spaces. Use camelCase or underscores if needed.

o Example: myVariable (valid), my Variable (invalid).

Valid Identifiers:

• myVar, num1, _count, $value, DataSet

Invalid Identifiers:

• 1stValue (starts with a digit)

• void (keyword)
• my Variable (contains space)

3. Literals (Constants)

• Literals are fixed values that do not change during program execution.

• They are directly assigned to variables.

Types of Literals:

1. Integer Literals: 100, -45, 0b101 (binary), 0x1A (hexadecimal)

2. Floating-point Literals: 3.14, -0.99, 2.5e3 (scientific notation)

3. Character Literals: 'A', '9', '#'

4. String Literals: "Hello", "Java"

5. Boolean Literals: true, false

6. Null Literal: null (represents absence of value)

4. Operators

• Operators are special symbols that perform operations on variables and values.

Types of Operators:

• Arithmetic Operators: +, -, *, /, %

• Relational Operators: ==, !=, >, <, >=, <=

• Logical Operators: &&, ||, !

• Assignment Operators: =, +=, -=, *=, /=, %=

• Bitwise Operators: &, |, ^, ~, <<, >>

• Ternary Operator: ?:

• Instanceof Operator: Checks if an object is an instance of a class.

5. Separators (Punctuators)

• Separators define the structure and organization of the code.

Common Separators:

• ; (Semicolon): Marks the end of a statement.

• , (Comma): Separates multiple variables or parameters.

• . (Dot): Accesses class members (e.g., System.out.println).

• () (Parentheses): Used in method calls and control structures.


• {} (Braces): Defines blocks of code.

• [] (Brackets): Defines arrays.

6. Comments

• Comments are ignored by the Java compiler. They are used to explain code for better
readability.

Types of Comments:

1. Single-line Comment:

// This is a single-line comment

2. Multi-line Comment:

/* This is a

multi-line comment */

3. Documentation Comment (for API docs):

/**

* This is a documentation comment

* Used for JavaDoc generation

*/

Quick Example with All Tokens:


package mypackage; // Keyword (package), Identifier
(mypackage), Separator (;)
import java.util.Scanner; // Keyword (import), Identifier
(java, util, Scanner), Separator (;)

public class Example { // Keywords (public, class),


Identifier (Example), Separator ({)
public static void main(String[] args) { // Keywords (public,
static, void), Identifier (main, String, args)

int number = 100; // Keyword (int), Identifier


(number), Literal (100), Operator (=), Separator (;)
String message = "Hello, Java!"; // Identifier (String,
message), Literal ("Hello, Java!")
if (number > 50) { // Keyword (if), Operator (>),
Separator ({)
System.out.println(message); // Identifier (System,
out, println), Separator ((), .)
} // Separator (})
} // Separator (})
} // Separator (})

Summary:

• Keywords: Reserved words with special meaning.

• Identifiers: Names for classes, variables, methods.

• Literals: Constant values like numbers, strings.

• Operators: Perform operations on variables.

• Separators: Organize code structure.

• Comments: Explain code, ignored by the compiler.

3. Constants

Constants are fixed values that do not change during program execution.

Declaring Constants:

• Using final Keyword:

final int MAX_VALUE = 100;

final double PI = 3.14159;

Types of Constants:

1. Integer Constants: 10, -20

2. Floating-point Constants: 3.14, -0.99

3. Character Constants: 'A', 'Z'

4. String Constants: "Hello", "Java"

5. Boolean Constants: true, false

4. Variables

Variables are containers that store data values.

Declaring Variables:
int age = 25;

double salary = 55000.50;

char grade = 'A';

boolean isActive = true;

Variable Types:

1. Local Variables: Declared inside methods or blocks.

2. Instance Variables: Belong to an instance of a class.

3. Static Variables: Shared among all instances of a class.

5. Expressions

An expression is a combination of variables, operators, and literals that produces a value.

Examples:

int result = 5 + 10; // Arithmetic Expression

boolean isEqual = (a == b); // Relational Expression

int sum = x + y * z; // Compound Expression

• Arithmetic Expressions: a + b, x * y

• Relational Expressions: x > y, a != b

• Logical Expressions: (a > b) && (c < d)

6. Decision-Making Statements (Control Flow)

Used to execute code conditionally.

a. if Statement:

if (age > 18) {

System.out.println("Adult");

b. if-else Statement:

if (score >= 50) {

System.out.println("Pass");

} else {

System.out.println("Fail");

}
c. else if Ladder:

if (marks >= 90) {

System.out.println("Grade A");

} else if (marks >= 75) {

System.out.println("Grade B");

} else {

System.out.println("Grade C");

d. switch Statement:

int day = 3;

switch (day) {

case 1: System.out.println("Monday"); break;

case 2: System.out.println("Tuesday"); break;

case 3: System.out.println("Wednesday"); break;

default: System.out.println("Invalid Day");

7. Looping Statements (Iteration)

Used to execute a block of code repeatedly.

a. for Loop:

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

System.out.println(i);

b. while Loop:

int i = 1;

while (i <= 5) {

System.out.println(i);

i++;

c. do-while Loop:

int i = 1;
do {

System.out.println(i);

i++;

} while (i <= 5);

d. Enhanced for Loop (for Arrays):

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

for (int num : numbers) {

System.out.println(num);

8️. Java Statements

A statement in Java is an instruction that performs an action.

Types of Statements:

1. Expression Statements:

o Perform operations and assignments.

o Example: int x = 10;, x++;, System.out.println("Hello");

2. Declaration Statements:

o Declare variables.

o Example: int a, b, c;

3. Control Flow Statements:

o Direct program flow (if, for, while, break, continue, return).

o Example:

if (x > 0) {

return x;

4. Block Statements:

o Group multiple statements inside {} braces.

o Example:

int a = 5;

int b = 10;
System.out.println(a + b);

Key Takeaways:

• Java programs are structured with classes, methods, and statements.

• Tokens are the building blocks (keywords, identifiers, literals, etc.).

• Constants (final) hold fixed values, while variables can change.

• Control flow (if-else, switch) and loops (for, while, do-while) manage program logic.

• Statements are instructions executed by the JVM.

1. Taking Input Using Scanner

The Scanner class is the most widely used method for taking input from the user. It is part of the
java.util package and provides various methods for reading different data types.

Steps to Use Scanner

1. Import java.util.Scanner at the beginning of the program.

2. Create an instance of Scanner class.

3. Use methods like nextInt(), nextDouble(), nextLine(), etc., to read input.

Example: Reading Different Data Types


Methods of Scanner Class

Method Description
nextInt() Reads an integer.
nextFloat() Reads a float number.
nextDouble() Reads a double number.
nextBoolean() Reads a boolean (true/false).
next() Reads a single word (stops at space).
nextLine() Reads a full line including spaces.
nextLong() Reads a long integer.
nextByte() Reads a byte value.

2. Taking Input Using BufferedReader

Another way to take input is using BufferedReader, which is faster but requires handling exceptions.

Example: Using BufferedReader

Why Use BufferedReader?

• Faster than Scanner

• Used in competitive programming

3. Taking Input Using Console (For Passwords)


The Console class is useful for hiding input, such as when entering passwords.
Example: Using Console

Why Use Console?

• Hides input (useful for passwords)

• Only works in real terminal (not in IDEs like Eclipse, IntelliJ)

4. Taking Input Using Command-Line Arguments


Java also allows input through command-line arguments when running the program.

Example: Using Command-Line Arguments

Run this program in terminal:


Coding Problems in Java
1. Print Numbers from 1 to N

Write a program that takes an integer N as input and prints numbers from 1 to N using a loop.

Example:

2. Print Even Numbers up to N

Write a program to print all even numbers from 1 to N.

Example:
3. Calculate the Sum of First N Natural Numbers

Write a program to calculate the sum of numbers from 1 to N.

Example:

4. Reverse a Number

Write a program to reverse the digits of an integer.

Example:
5. Find Factorial of a Number

Write a program to compute the factorial of a given number N.

Example:
6. Check if a Number is Prime

Write a program to check whether a number N is prime.

Example:

7. Find the Sum of Digits of a Number

Write a program to compute the sum of the digits of a number.

Example:
8️. Fibonacci Series up to N Terms

Write a program to print the Fibonacci series up to N terms.

Example (n = 7):
9. Print a Star Pattern

Write a program to print a right-angled triangle pattern.

Example (n = 4):

10. Find the Greatest Common Divisor (GCD)

Write a program to find the GCD (Greatest Common Divisor) of two numbers.

Example:
Task: "Guess the Secret Number"

Problem Statement: Create a Java program where the computer randomly selects a number
between 1 and 100. The player has to guess the number. After each guess, the program should give
hints:

• "Too High" if the guess is higher than the secret number.

• "Too Low" if the guess is lower than the secret number.

• "Correct!" if the guess matches the number.

Key Concepts Covered:

• while loops and do-while loops

• if-else conditions

• Random number generation (Math.random())

• User input with Scanner

• Basic error handling with try-catch (optional challenge)


Variants of for loop in Java

int n;
for(n=10; n>0; n--)
System.out.println("tick " + n);

for(int n=10; n>0; n--)


System.out.println("tick " + n);

Example: // Test for primes.


class FindPrime {
public static void main(String args[]) {
int num;
boolean isPrime;
num = 14;
if(num < 2) isPrime = false;
else isPrime = true;
for(int i=2; i <= num/i; i++) {
if((num % i) == 0) {
isPrime = false;
break;
}
}
if(isPrime) System.out.println("Prime");
else System.out.println("Not Prime");
}
}

int a, b;
for (a=1, b=4; a<b; a++, b--) {
System.out.println("a = " + a);
System.out.println("b = " + b);
}

boolean done = false;


for(int i=1; !done; i++) {
if(interrupted()) done = true;
}

int i;
boolean done = false;
i = 0;
for( ; !done; ) {
System.out.println("i is " + i);
if(i == 10) done = true;
i++;
}

for( ; ; ) {
// ...
}

The For-Each Version of the for Loop


A for-each style loop is designed to cycle through a collection of objects, such as an array, in strictly

sequential fashion, from start to finish.

The general form of the for-each version of the for is shown here:
for (type itr-var : collection) statement-block

int nums[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int sum = 0;
for (int x: nums)
sum += x;
for(int x : nums) {
System.out.println("Value is: " + x);
sum += x;
}

for(int x : nums) {
System.out.println("Value is: " + x);
sum += x;
if(x == 5) break; // stop the loop when 5 is obtained
}

// Search an array using for-each style for.


class Search {
public static void main(String args[]) {
int nums[] = { 6, 8, 3, 7, 5, 6, 1, 4 };
int val = 5;
boolean found = false;
// use for-each style for to search nums for val
for(int x : nums) {
if(x == val) {
found = true;
break;
}
}
if(found)
System.out.println("Value found!");
}

Detailed Notes on Arrays in Java

1. What is an Array?
• An array is a data structure in Java that stores a fixed-size sequential collection of elements
of the same type.

• It is a contiguous block of memory where each element is accessed using its index.

2. Key Features of Arrays

• Fixed Size: Once an array is created, its size cannot be changed.

• Zero-based Indexing: The first element is at index 0, the second at 1, and so on.

• Homogeneous Elements: All elements in an array must be of the same data type.

• Stored in Contiguous Memory Locations: Elements are stored one after the other in
memory.

3. Declaring an Array

To declare an array, you specify:

• Data type of the elements

• Square brackets [] to denote it's an array

• Variable name

dataType[] arrayName; // Recommended syntax

// OR

dataType arrayName[];

Examples

int[] numbers; // Declaration of an integer array

String[] names; // Declaration of a String array

double[] scores; // Declaration of a double array

4. Instantiating an Array

Arrays must be initialized with a specific size using the new keyword.

arrayName = new dataType[size];

Example

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

5. Initializing an Array

Arrays can be initialized in the following ways:


(a) Default Initialization

When an array is created, all elements are automatically initialized to their default values:

• 0 for numeric types (int, double, long, etc.)

• false for boolean

• null for object types (String, etc.)

Example:

int[] numbers = new int[5]; // All elements will be 0 by default

(b) Explicit Initialization

You can explicitly initialize an array using curly braces {}.

Example:

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

String[] names = {"Alice", "Bob", "Charlie"};

(c) Partial Initialization

If you initialize only some elements, the rest will take the default values.

Example:

int[] numbers = new int[5];

numbers[0] = 10; // First element set to 10

6. Accessing Array Elements

• Array elements are accessed using their index (starting from 0).

• Use the syntax arrayName[index].

Example

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

System.out.println(numbers[0]); // Outputs 10

System.out.println(numbers[2]); // Outputs 30

7. Iterating Through an Array

(a) Using a for Loop

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


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

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

(b) Using an Enhanced for Loop

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

for (int num : numbers) {

System.out.println(num);

8️. Types of Arrays

(a) One-Dimensional Arrays

• A simple list of elements.

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

(b) Multi-Dimensional Arrays

• Arrays that contain other arrays as elements.

• Most common type: 2D Array (Matrix).

Example:

int[][] matrix = {

{1, 2, 3},

{4, 5, 6},

{7, 8, 9}

};

System.out.println(matrix[1][2]); // Accesses element at 2nd row, 3rd column -> Outputs 6

(c) Jagged Arrays

• Multi-dimensional arrays with rows of different lengths.

int[][] jaggedArray = {

{1, 2, 3},

{4, 5},

{6, 7, 8, 9}

};
9. Array Length

• Use the .length property to get the size of the array.

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

System.out.println(numbers.length); // Outputs 3

10. Common Operations on Arrays

(a) Copying Arrays

Using System.arraycopy():

int[] source = {1, 2, 3};

int[] destination = new int[source.length];

System.arraycopy(source, 0, destination, 0, source.length);

Arrays Class in Java

The java.util.Arrays class is part of the Java Collections Framework and provides utility methods to
work with arrays. It simplifies tasks such as sorting, searching, copying, and comparing arrays.

1.1 Key Features of the Arrays Class

• Provides static utility methods for working with arrays.

• Designed specifically for manipulating arrays of any data type.

• Belongs to the java.util package.

1.2 Common Methods of the Arrays Class

Here is a list of the most frequently used methods of the Arrays class:

Method Description

Arrays.sort(array) Sorts the array in ascending order.

Searches for a specific element (key) in a sorted array using binary


Arrays.binarySearch(array, key)
search. Returns the index if found.

Compares two arrays for equality. Returns true if both arrays are of
Arrays.equals(arr1, arr2)
the same length and have identical elements.
Method Description

Arrays.copyOf(array,
Copies the specified array into a new array of a specified length.
newLength)

Arrays.copyOfRange(array,
Copies a range of elements from the array into a new array.
from, to)

Arrays.fill(array, value) Fills the entire array with a specific value.

Arrays.toString(array) Returns a string representation of the array.

Arrays.stream(array) Converts an array into a stream (useful for Java Stream API).

Arrays.asList(array) Converts an array into a List.

Returns the index of the first mismatch between two arrays, or -1


Arrays.mismatch(arr1, arr2)
if they are identical.

1.3 Examples of Using Arrays Class

(a) Sorting an Array

import java.util.Arrays;

public class ArraysExample {

public static void main(String[] args) {

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

Arrays.sort(numbers); // Sort the array in ascending order

System.out.println("Sorted Array: " + Arrays.toString(numbers));

Output:

Sorted Array: [1, 2, 3, 5, 8️]

(b) Binary Search

import java.util.Arrays;

public class ArraysExample {

public static void main(String[] args) {

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

int index = Arrays.binarySearch(numbers, 5); // Search for the element 5


System.out.println("Index of 5: " + index);

Output:

Index of 5: 3

(c) Comparing Two Arrays

import java.util.Arrays;

public class ArraysExample {

public static void main(String[] args) {

int[] arr1 = {1, 2, 3};

int[] arr2 = {1, 2, 3};

boolean isEqual = Arrays.equals(arr1, arr2);

System.out.println("Arrays are equal: " + isEqual);

Output:

Arrays are equal: true

(d) Filling an Array

import java.util.Arrays;

public class ArraysExample {

public static void main(String[] args) {

int[] numbers = new int[5];

Arrays.fill(numbers, 42); // Fill all elements with 42

System.out.println("Filled Array: " + Arrays.toString(numbers));

Output:

Filled Array: [42, 42, 42, 42, 42]


11. Limitations of Arrays

• Fixed Size: Cannot resize once initialized.

• Homogeneity: Can only store one type of data.

12. Advantages of Arrays

• Fast Access: O(1) time complexity for accessing elements.

• Memory Efficiency: Uses contiguous memory locations.

13. Example Programs

(a) Reverse an Array

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

for (int i = arr.length - 1; i >= 0; i--) {

System.out.print(arr[i] + " ");

(b) Find the Maximum Element

int[] arr = {10, 20, 5, 15};

int max = arr[0];

for (int i = 1; i < arr.length; i++) {

if (arr[i] > max) {

max = arr[i];

System.out.println("Maximum: " + max);

(c) Matrix Multiplication (2D Arrays)

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

int[][] B = {{5, 6}, {7, 8}};

int[][] C = new int[2][2];

for (int i = 0; i < 2; i++) {

for (int j = 0; j < 2; j++) {


C[i][j] = 0;

for (int k = 0; k < 2; k++) {

C[i][j] += A[i][k] * B[k][j];

// Print Resultant Matrix

for (int[] row : C) {

for (int val : row) {

System.out.print(val + " ");

System.out.println();

Java Collections Framework?


Any group of individual objects that are represented as a single unit is known as a Java Collection of
Objects. In Java, a separate framework named the “Collection Framework” has been defined in JDK 1.2
which holds all the Java Collection Classes and Interface in it.

In Java, the Collection interface (java.util.Collection) and Map interface (java.util.Map) are the two
main “root” interfaces of Java collection classes.

The Java Collections Framework (JCF) is a set of classes and interfaces that provide reusable data
structures and algorithms for working with collections of objects. A collection is a group of individual
objects that are treated as a single unit, such as lists, sets, and maps.
Before the Collection Framework(or before JDK 1.2) was introduced, the standard methods for
grouping Java objects (or collections) were Arrays or Vectors, or Hashtables. All of these collections
had no common interface. Therefore, though the main aim of all the collections is the same, the
implementation of all these collections was defined independently and had no correlation among
them. And also, it is very difficult for the users to remember all the different methods, syntax,
and constructors present in every collection class.

Advantages of the Java Collections Framework

1. Reusable Code: Common data structures and algorithms are provided as reusable classes.

2. Ease of Development: Simplifies complex data manipulation tasks like sorting, searching, and
iteration.

3. Performance: Provides high-performance data structures.

4. Interoperability: Unified interfaces make it easy to switch between different data structures.

5. Thread Safety: Includes thread-safe implementations like Vector and Hashtable and provides
utilities for synchronization.

Data Structures in the Collections Framework


The Collections Framework in Java provides a set of data structures that help store,
manipulate, and manage data efficiently. Below are the major data structures:
1. List Interface (Ordered, allows duplicates)
• ArrayList: Resizable array, fast random access (O(1)), slow insertions/deletions
(O(n)).
• LinkedList: Doubly linked list, fast insertions/deletions (O(1)), slow random access
(O(n)).
• Vector: Like ArrayList, but synchronized (thread-safe).
• Stack: A LIFO (Last-In-First-Out) structure based on Vector.
2. Set Interface (Unique elements, unordered)
• HashSet: Uses a HashMap internally, unordered, allows null, O(1) operations.
• LinkedHashSet: Like HashSet but maintains insertion order.
• TreeSet: Implements NavigableSet, sorted order (Red-Black Tree), O(log n)
operations.
3. Queue Interface (FIFO - First-In-First-Out)
• PriorityQueue: Elements sorted based on natural ordering or custom comparator.
• ArrayDeque: A resizable array-based deque (double-ended queue), can be used as
a Stack or Queue.
4. Map Interface (Key-Value pairs, unique keys)
• HashMap: Unordered, allows null keys and values, O(1) operations.
• LinkedHashMap: Maintains insertion order.
• TreeMap: Sorted order (Red-Black Tree), O(log n) operations.
• Hashtable: Like HashMap, but synchronized (thread-safe), doesn't allow null
keys/values.

1. List Interface (Ordered, allows duplicates)


ArrayList Example
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("Apple");
list.add("Banana");
list.add("Cherry");
System.out.println(list); // Output: [Apple, Banana, Cherry]
}
}
LinkedList Example
import java.util.LinkedList;

public class Main {


public static void main(String[] args) {
LinkedList<Integer> list = new LinkedList<>();
list.add(10);
list.add(20);
list.addFirst(5);
System.out.println(list); // Output: [5, 10, 20]
}
}
Vector Example
import java.util.Vector;
public class Main {
public static void main(String[] args) {
Vector<String> vector = new Vector<>();
vector.add("Dog");
vector.add("Cat");
vector.add("Elephant");
System.out.println(vector); // Output: [Dog, Cat, Elephant]
}
}
Stack Example
import java.util.Stack;
public class Main {
public static void main(String[] args) {
Stack<Integer> stack = new Stack<>();
stack.push(1);
stack.push(2);
stack.push(3);
System.out.println(stack.pop()); // Output: 3 (Last-in, first-out)
}
}
2. Set Interface (Unique elements, unordered)
HashSet Example
import java.util.HashSet;
public class Main {
public static void main(String[] args) {
HashSet<String> set = new HashSet<>();
set.add("Red");
set.add("Green");
set.add("Blue");
set.add("Red"); // Duplicate, ignored
System.out.println(set); // Output: [Red, Green, Blue] (Unordered)
}
}
LinkedHashSet Example
import java.util.LinkedHashSet;

public class Main {


public static void main(String[] args) {
LinkedHashSet<Integer> set = new LinkedHashSet<>();
set.add(100);
set.add(50);
set.add(150);
System.out.println(set); // Output: [100, 50, 150] (Maintains
insertion order)
}
}
TreeSet Example
import java.util.TreeSet;

public class Main {


public static void main(String[] args) {
TreeSet<Integer> set = new TreeSet<>();
set.add(30);
set.add(10);
set.add(20);
System.out.println(set); // Output: [10, 20, 30] (Sorted order)
}
}

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


PriorityQueue Example
import java.util.PriorityQueue;
public class Main {
public static void main(String[] args) {
PriorityQueue<Integer> queue = new PriorityQueue<>();
queue.add(30);
queue.add(10);
queue.add(20);
System.out.println(queue.poll()); // Output: 10 (Smallest element
first)
}
}
ArrayDeque Example
import java.util.ArrayDeque;
public class Main {
public static void main(String[] args) {
ArrayDeque<String> deque = new ArrayDeque<>();
deque.add("A");
deque.addLast("B");
deque.addFirst("C");
System.out.println(deque); // Output: [C, A, B]
}
}

4. Map Interface (Key-Value pairs, unique keys)


HashMap Example
import java.util.HashMap;
public class Main {
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.get(2)); // Output: Two
}
}
LinkedHashMap Example
import java.util.LinkedHashMap;
public class Main {
public static void main(String[] args) {
LinkedHashMap<Integer, String> map = new LinkedHashMap<>();
map.put(3, "C");
map.put(1, "A");
map.put(2, "B");
System.out.println(map); // Output: {3=C, 1=A, 2=B} (Maintains
insertion order)
}
}
TreeMap Example
import java.util.TreeMap;

public class Main {


public static void main(String[] args) {
TreeMap<Integer, String> map = new TreeMap<>();
map.put(3, "Three");
map.put(1, "One");
map.put(2, "Two");
System.out.println(map); // Output: {1=One, 2=Two, 3=Three}
(Sorted order)
}
}
Hashtable Example
import java.util.Hashtable;

public class Main {


public static void main(String[] args) {
Hashtable<Integer, String> table = new Hashtable<>();
table.put(101, "Alice");
table.put(102, "Bob");
System.out.println(table.get(101)); // Output: Alice
}
}
Hierarchy of Java Collections Framework
The utility package, (java.util) contains all the classes and interfaces that are required by
the collection framework. The collection framework contains an interface named an
iterable interface which provides the iterator to iterate through all the collections. This
interface is extended by the main collection interface which acts as a root for the collection
framework. All the collections extend this collection interface thereby extending the
properties of the iterator and the methods of this interface. The following figure illustrates
the hierarchy of the collection framework.

Before understanding the different components in the above framework, let’s first
understand a class and an interface.
• Class: A class is a user-defined blueprint or prototype from which objects are
created. It represents the set of properties or methods that are common to all
objects of one type.
• Interface: Like a class, an interface can have methods and variables, but the
methods declared in an interface are by default abstract (only method signature,
nobody). Interfaces specify what a class must do and not how. It is the blueprint of
the class.

Methods of the Collection Interface


This interface contains various methods which can be directly used by all the collections
which implement this interface. They are:
Method Description
add(Object) This method is used to add an object to the collection.
addAll(Collection c) This method adds all the elements in the given collection
to this collection.
clear() This method removes all of the elements from this
collection.
contains(Object o) This method returns true if the collection contains the
specified element.
containsAll(Collection c) This method returns true if the collection contains all of the
elements in the given collection.
equals(Object o) This method compares the specified object with this
collection for equality.
hashCode() This method is used to return the hash code value for this
collection.
isEmpty() This method returns true if this collection contains no
elements.
iterator() This method returns an iterator over the elements in this
collection.
max() This method is used to return the maximum value present
in the collection.
parallelStream() This method returns a parallel Stream with this collection
as its source.
remove(Object o) This method is used to remove the given object from the
collection. If there are duplicate values, then this method
removes the first occurrence of the object.
removeAll(Collection c) This method is used to remove all the objects mentioned in
the given collection from the collection.
removeIf(Predicate filter) This method is used to remove all the elements of this
collection that satisfy the given predicate.
retainAll(Collection c) This method is used to retain only the elements in this
collection that are contained in the specified collection.
size() This method is used to return the number of elements in
the collection.
spliterator() This method is used to create a Spliterator over the
elements in this collection.
stream() This method is used to return a sequential Stream with this
collection as its source.
toArray() This method is used to return an array containing all of the
elements in this collection.

Interfaces that Extend the Java Collections Interface


The collection framework contains multiple interfaces where every interface is used to store a specific
type of data. The following are the interfaces present in the framework.

1. Iterable Interface: This is the root interface for the entire collection framework. The collection
interface extends the iterable interface. Therefore, inherently, all the interfaces and classes implement
this interface. The main functionality of this interface is to provide an iterator for the collections.
Therefore, this interface contains only one abstract method which is the iterator. It returns the

Iterator iterator();
2. Collection Interface: This interface extends the iterable interface and is implemented by all the
classes in the collection framework. This interface contains all the basic methods which every
collection has like adding the data into the collection, removing the data, clearing the data, etc. All
these methods are implemented in this interface because these methods are implemented by all the
classes irrespective of their style of implementation. And also, having these methods in this interface
ensures that the names of the methods are universal for all the collections. Therefore, in short, we can
say that this interface builds a foundation on which the collection classes are implemented.

3. List Interface: This is a child interface of the collection interface. This interface is dedicated to the
data of the list type in which we can store all the ordered collections of the objects. This also allows
duplicate data to be present in it. This list interface is implemented by various classes like ArrayList,
Vector, Stack, etc. Since all the subclasses implement the list, we can instantiate a list object with any
of these classes.

For example:

List <T> al = new ArrayList<> (int size);


List <T> ll = new LinkedList<> (int size);
List <T> v = new Vector<> (int size);
Where T is the type of the object

The classes which implement the List interface are as follows:

i). ArrayList: ArrayList provides us with dynamic arrays in Java. Though, it may be slower than standard
arrays but can be helpful in programs where lots of manipulation in the array is needed. The size of an
ArrayList is increased automatically if the collection grows or shrinks if the objects are removed from
the collection. Java ArrayList allows us to randomly access the list. ArrayList cannot be used
for primitive types, like int, char, etc. We will need a wrapper class for such cases. Initial Size: The
default capacity of an ArrayList is 10 if created using the default constructor. Capacity Growth: When
the ArrayList exceeds its current capacity, it grows by 50% (i.e., new capacity = old capacity × 1.5).
Let’s understand the ArrayList with the following example:
// Java program to demonstrate the working of ArrayList
import java.io.*;
import java.util.*;
class GFG {
public static void main(String[] args)
{
// Declaring the ArrayList with initial size n
ArrayList<Integer> al = new ArrayList<Integer>();

// Appending new elements at the end of the list


for (int i = 1; i <= 5; i++)
al.add(i);

// Printing elements
System.out.println(al);

// Remove element at index 3


al.remove(3);

// Displaying the ArrayList after deletion


System.out.println(al);
//Printing elements one by one
for (int i = 0; i < al.size(); i++)
System.out.print(al.get(i) + " ");
}
}
Output
[1, 2, 3, 4, 5]
[1, 2, 3, 5]
1235

ii). LinkedList: The LinkedList class is an implementation of the LinkedList data structure which is a
linear data structure where the elements are not stored in contiguous locations and every element is
a separate object with a data part and address part. The elements are linked using pointers and
addresses. Each element is known as a node.
Let’s understand the LinkedList with the following example:
// Java program to demonstrate the working of LinkedList
import java.io.*;
import java.util.*;
class GFG {
public static void main(String[] args)
{
// Declaring the LinkedList
LinkedList<Integer> ll = new LinkedList<Integer>();

// Appending new elements at the end of the list


for (int i = 1; i <= 5; i++)
ll.add(i);

// Printing elements
System.out.println(ll);

// Remove element at index 3


ll.remove(3);

// Displaying the List after deletion


System.out.println(ll);

// Printing elements one by one


for (int i = 0; i < ll.size(); i++)
System.out.print(ll.get(i) + " ");
}
}

Output
[1, 2, 3, 4, 5]
[1, 2, 3, 5]
1235

iii). Vector: A vector provides us with dynamic arrays in Java. Though, it may be slower than standard
arrays but can be helpful in programs where lots of manipulation in the array is needed. This is identical
to ArrayList in terms of implementation. However, the primary difference between a vector and an
ArrayList is that a Vector is synchronized and an ArrayList is non-synchronized. Initial Size: The default
capacity of a Vector is 10 if created using the default constructor. Capacity Growth: When the Vector
exceeds its current capacity, it doubles its size (i.e., new capacity = old capacity × 2).
Let’s understand the Vector with an example:
// Java program to demonstrate the working of Vector
import java.io.*;
import java.util.*;
class GFG {
public static void main(String[] args)
{
// Declaring the Vector
Vector<Integer> v = new Vector<Integer>();

// Appending new elements at the end of the list


for (int i = 1; i <= 5; i++)
v.add(i);
// Printing elements
System.out.println(v);
// Remove element at index 3
v.remove(3);
// Displaying the Vector after deletion
System.out.println(v);
// Printing elements one by one
for (int i = 0; i < v.size(); i++)
System.out.print(v.get(i) + " ");
}
}

Output
[1, 2, 3, 4, 5]
[1, 2, 3, 5]
1235

iv). Stack

Stack class models and implements the Stack data structure. The class is based on the basic principle
of last-in-first-out. In addition to the basic push and pop operations, the class provides three more
functions empty, search, and peek. The class can also be referred to as the subclass of Vector.
Let’s understand the stack with an example:
// Java program to demonstrate the working of a stack
import java.util.*;
public class GFG {
public static void main(String args[])
{
Stack<String> stack = new Stack<String>();
stack.push("Geeks");
stack.push("For");
stack.push("Geeks");
stack.push("Geeks");
// Iterator for the stack
Iterator<String> itr = stack.iterator();
// Printing the stack
while (itr.hasNext()) {
System.out.print(itr.next() + " ");
}
System.out.println();
stack.pop();

// Iterator for the stack


itr = stack.iterator();

// Printing the stack


while (itr.hasNext()) {
System.out.print(itr.next() + " ");
}
}
}

Output
Geeks For Geeks Geeks
Geeks For Geeks

Note: Stack is a subclass of Vector and a legacy class. It is thread-safe which might be overhead in an
environment where thread safety is not needed. An alternate to Stack is to use ArrayDequeue which is
not thread-safe and has faster array implementation.

4. Queue Interface

As the name suggests, a queue interface maintains the FIFO(First In First Out) order similar to a real-
world queue line. This interface is dedicated to storing all the elements where the order of the
elements matter. For example, whenever we try to book a ticket, the tickets are sold on a first come
first serve basis. Therefore, the person whose request arrives first into the queue gets the ticket. There
are various classes like PriorityQueue, ArrayDeque, etc. Since all these subclasses implement the
queue, we can instantiate a queue object with any of these classes.

For example:

Queue <T> pq = new PriorityQueue<> ();


Queue <T> ad = new ArrayDeque<> ();
Where T is the type of the object.

The most frequently used implementation of the queue interface is the PriorityQueue.

i. Priority Queue: A PriorityQueue is used when the objects are supposed to be processed based on
priority. It is known that a queue follows the First-In-First-Out algorithm, but sometimes the elements
of the queue are needed to be processed according to the priority and this class is used in these cases.
The PriorityQueue is based on the priority heap. The elements of the priority queue are ordered
according to the natural ordering, or by a Comparator provided at queue construction time, depending
on which constructor is used.

Let’s understand the priority queue with an example:


// Java program to demonstrate the working of priority queue in Java
import java.util.*;
class GfG {
public static void main(String args[])
{
// Creating empty priority queue
PriorityQueue<Integer> pQueue = new PriorityQueue<Integer>();

// Adding items to the pQueue using add()


pQueue.add(10);
pQueue.add(20);
pQueue.add(15);

// Printing the top element of PriorityQueue


System.out.println(pQueue.peek());

// Printing the top element and removing it from the PriorityQueue container
System.out.println(pQueue.poll());

// Printing the top element again


System.out.println(pQueue.peek());
}
}

Output
10
10
15

5. Deque Interface

This is a very slight variation of the queue data structure. Deque, also known as a double-ended queue,
is a data structure where we can add and remove elements from both ends of the queue. This interface
extends the queue interface. The class which implements this interface is ArrayDeque. Since
ArrayDeque class implements the Deque interface, we can instantiate a deque object with this class.

For example:

Deque<T> ad = new ArrayDeque<> ();


Where T is the type of the object.

The class which implements the deque interface is ArrayDeque.

ArrayDeque: ArrayDeque class which is implemented in the collection framework provides us with a
way to apply resizable array. This is a special kind of array that grows and allows users to add or remove
an element from both sides of the queue. Array deques have no capacity restrictions and they grow as
necessary to support usage.

Let’s understand ArrayDeque with an example:


// Java program to demonstrate the ArrayDeque class in Java
import java.util.*;
public class ArrayDequeDemo {
public static void main(String[] args)
{
// Initializing an deque
ArrayDeque<Integer> de_que = new ArrayDeque<Integer>(10);

// add() method to insert


de_que.add(10);
de_que.add(20);
de_que.add(30);
de_que.add(40);
de_que.add(50);
System.out.println(de_que);

// clear() method
de_que.clear();

// addFirst() method to insert the elements at the head


de_que.addFirst(564);
de_que.addFirst(291);

// addLast() method to insert the elements at the tail


de_que.addLast(24);
de_que.addLast(14);
System.out.println(de_que);
}
}

Output
[10, 20, 30, 40, 50]
[291, 564, 24, 14]

6. Set Interface

A set is an unordered collection of objects in which duplicate values cannot be stored. This collection
is used when we wish to avoid the duplication of the objects and wish to store only the unique objects.
This set interface is implemented by various classes like HashSet, TreeSet, LinkedHashSet, etc. Since
all the subclasses implement the set, we can instantiate a set object with any of these classes.

For example:

Set<T> hs = new HashSet<> ();


Set<T> lhs = new LinkedHashSet<> ();
Set<T> ts = new TreeSet<> ();
Where T is the type of the object.

The following are the classes that implement the Set interface:

i). HashSet: The HashSet class is an inherent implementation of the hash table data structure. The
objects that we insert into the HashSet do not guarantee to be inserted in the same order. The objects
are inserted based on their hashcode. This class also allows the insertion of NULL elements. Let’s
understand HashSet with an example:
// Java program to demonstrate the working of a HashSet
import java.util.*;
public class HashSetDemo {
public static void main(String args[])
{
// Creating HashSet and adding elements
HashSet<String> hs = new HashSet<String>();

hs.add("Geeks");
hs.add("For");
hs.add("Geeks");
hs.add("Is");
hs.add("Very helpful");

// Traversing elements
Iterator<String> itr = hs.iterator();
while (itr.hasNext()) {
System.out.println(itr.next());
}
}
}

Output
Very helpful
Geeks
For
Is

ii). LinkedHashSet

A LinkedHashSet is very similar to a HashSet. The difference is that this uses a doubly linked list to store
the data and retains the ordering of the elements.

Let’s understand the LinkedHashSet with an example:


// Java program to demonstrate the working of a LinkedHashSet
import java.util.*;
public class LinkedHashSetDemo {
public static void main(String args[])
{
// Creating LinkedHashSet and adding elements
LinkedHashSet<String> lhs = new LinkedHashSet<String>();

lhs.add("Geeks");
lhs.add("For");
lhs.add("Geeks");
lhs.add("Is");
lhs.add("Very helpful");

// Traversing elements
Iterator<String> itr = lhs.iterator();
while (itr.hasNext()) {
System.out.println(itr.next());
}
}
}

Output
Geeks
For
Is
Very helpful

7. Sorted Set Interface

This interface is very similar to the set interface. The only difference is that this interface has extra
methods that maintain the ordering of the elements. The sorted set interface extends the set interface
and is used to handle the data which needs to be sorted. The class which implements this interface is
TreeSet. Since this class implements the SortedSet, we can instantiate a SortedSet object with this
class.

For example:

SortedSet<T> ts = new TreeSet<> ();


Where T is the type of the object.

The class which implements the sorted set interface is TreeSet.

TreeSet

The TreeSet class uses a Tree for storage. The ordering of the elements is maintained by a set using
their natural ordering whether or not an explicit comparator is provided. This must be consistent with
equals if it is to correctly implement the Set interface. It can also be ordered by a Comparator provided
at a set creation time, depending on which constructor is used.

Let’s understand TreeSet with an example:


// Java program to demonstrate the working of a TreeSet
import java.util.*;
public class TreeSetDemo {
public static void main(String args[])
{
// Creating TreeSet and adding elements
TreeSet<String> ts = new TreeSet<String>();

ts.add("Geeks");
ts.add("For");
ts.add("Geeks");
ts.add("Is");
ts.add("Very helpful");

// Traversing elements
Iterator<String> itr = ts.iterator();
while (itr.hasNext()) {
System.out.println(itr.next());
}
}
}

Output
For
Geeks
Is
Very helpful

8️. Map Interface

A map is a data structure that supports the key-value pair for mapping the data. This interface doesn’t
support duplicate keys because the same key cannot have multiple mappings, however, it allows
duplicate values in different keys. A map is useful if there is data and we wish to perform operations
on the basis of the key. This map interface is implemented by various classes like HashMap, TreeMap,
etc. Since all the subclasses implement the map, we can instantiate a map object with any of these
classes.

For example:

Map<T> hm = new HashMap<> ();


Map<T> tm = new TreeMap<> ();

Where T is the type of the object.

The frequently used implementation of a Map interface is a HashMap.

HashMap: HashMap provides the basic implementation of the Map interface of Java. It stores the data
in (Key, Value) pairs. To access a value in a HashMap, we must know its key. HashMap uses a technique
called Hashing. Hashing is a technique of converting a large String to a small String that represents the
same String so that the indexing and search operations are faster. HashSet also uses HashMap
internally.

Let’s understand the HashMap with an example:

// Java program to demonstrate the working of a HashMap


import java.util.*;
public class HashMapDemo {
public static void main(String args[])
{
// Creating HashMap and adding elements
HashMap<Integer, String> hm= new HashMap<Integer, String>();

hm.put(1, "Geeks");
hm.put(2, "For");
hm.put(3, "Geeks");

// Finding the value for a key


System.out.println("Value for 1 is " + hm.get(1));

// Traversing through the HashMap


for (Map.Entry<Integer, String> e : hm.entrySet())
System.out.println(e.getKey() + " " + e.getValue());
}
}

Output
Value for 1 is Geeks
1 Geeks
2 For
3 Geeks

1. Interfaces

The core interfaces define the types of collections in JCF. Key ones include:

Interface Description

Collection The root interface for handling groups of objects (e.g., List, Set, Queue).

List Ordered collection that allows duplicate elements (e.g., ArrayList, LinkedList).

Set Collection that does not allow duplicate elements (e.g., HashSet, TreeSet).

Queue Collection designed for holding elements prior to processing (e.g., PriorityQueue).

Deque Double-ended queue for adding/removing elements from both ends (e.g., ArrayDeque).

Map A mapping of unique keys to values (e.g., HashMap, TreeMap, LinkedHashMap).

SortedSet A Set that maintains sorted order (e.g., TreeSet).

SortedMap A Map that maintains sorted order of keys (e.g., TreeMap).

2. Implementations (Classes)

Java provides several ready-to-use classes that implement the above interfaces.
Interface
Class Description
Implemented

ArrayList List Dynamic array that allows random access and resizing.

LinkedList List, Deque Doubly linked list for efficient insertions and deletions.

HashSet Set Unordered collection with no duplicates.

Sorted collection with no duplicates (implements Red-Black


TreeSet SortedSet
Tree).

HashMap Map Key-value pair with fast lookups; allows one null key.

TreeMap SortedMap Key-value pair sorted by keys.

LinkedHashMap Map Maintains insertion order of elements.

Elements processed based on priority (natural ordering or


PriorityQueue Queue
comparator).

ArrayDeque Deque Resizable array implementation of a double-ended queue.

Legacy dynamic array; synchronized (not recommended for


Vector List
modern use).

Stack Vector Last-In-First-Out (LIFO) stack.

Methods in the Java Collections Framework

Category Method Description Example

Adds an element to the


Collection add(E e) list.add("Apple");
collection.

addAll(Collection<? Adds all elements from a


list.addAll(anotherList);
extends E> c) specified collection.

Removes a specific element


remove(Object o) list.remove("Apple");
from the collection.

Removes all elements in the


removeAll(Collection<?> c) list.removeAll(anotherList);
specified collection.

Retains only the elements


retainAll(Collection<?> c) present in the specified list.retainAll(anotherList);
collection.
Category Method Description Example

Removes all elements from


clear() list.clear();
the collection.

Checks if the collection


contains(Object o) list.contains("Apple");
contains a specific element.

Checks if the collection


containsAll(Collection<?>
contains all elements from list.containsAll(anotherList);
c)
the specified collection.

Checks if the collection is


isEmpty() list.isEmpty();
empty.

Returns the number of


size() int size = list.size();
elements in the collection.

Returns an iterator to Iterator<String> it =


iterator()
traverse the collection. list.iterator();

Converts the collection into


toArray() Object[] array = list.toArray();
an array.

Category Method Description Example

List (ArrayList, Retrieves the element at a


get(int index) list.get(2);
LinkedList) specified position.

set(int index, E Replaces the element at a


list.set(1, "Banana");
element) specified position.

Returns the index of the


indexOf(Object o) first occurrence of the list.indexOf("Apple");
element.

Returns the index of the


lastIndexOf(Object o) last occurrence of the list.lastIndexOf("Apple");
element.

Returns a view of the


subList(int fromIndex, List<String> subList =
specified portion of the
int toIndex) list.subList(1, 3);
list.

Category Method Description Example

Set add(E e) Adds an element to the set. set.add("Apple");


Category Method Description Example

remove(Object o) Removes a specific element from the set. set.remove("Apple");

contains(Object o) Checks if the set contains a specific element. set.contains("Apple");

isEmpty() Checks if the set is empty. set.isEmpty();

size() Returns the number of elements in the set. int size = set.size();

Category Method Description Example

Map
Adds a key-value pair
(HashMap, put(K key, V value) map.put(1, "Apple");
to the map.
TreeMap)

Retrieves the value


get(Object key) associated with the String value = map.get(1);
given key.

Removes the key-


remove(Object key) value pair for the map.remove(1);
specified key.

Checks if the map


containsKey(Object
contains the map.containsKey(1);
key)
specified key.

Checks if the map


containsValue(Object
contains the map.containsValue("Apple");
value)
specified value.

Returns a set of all


keySet() Set<Integer> keys = map.keySet();
keys in the map.

Returns a collection
Collection<String> values =
values() of all values in the
map.values();
map.

Returns a set of key-


for (Map.Entry<Integer, String>
entrySet() value pairs as
entry : map.entrySet()) { ... }
Map.Entry objects.

Comparison of Collection Types


Feature List Set Map

Duplicates Allowed Not Allowed Keys: No, Values: Yes

Ordering Maintained Depends Depends

Yes (one key, multiple


Null Values Yes (multiple) Yes (only one)
values)

Depends on Depends on
Performance Depends on implementation
implementation implementation

Key Differences Between Collections and Arrays

1. Collections can dynamically grow and shrink in size, whereas arrays are fixed in size.

2. Collections offer built-in methods for manipulation, such as sorting, whereas arrays require
manual handling.

3. Collections can store objects only, while arrays can store primitives and objects.

Best Practices

1. Choose the correct data structure based on the requirement (e.g., use List for ordered data,
Set for unique elements).

2. Prefer ArrayList over Vector unless thread safety is required.

3. Use generic types to avoid ClassCastException.

4. Use Collections.unmodifiableList() to create read-only collections if needed.

Dynamic Arrays in Java

Java does not provide built-in support for dynamic arrays (like Python’s lists). However, dynamic
arrays can be implemented in Java using the following methods:

1. Using ArrayList from the java.util Package

Java provides the ArrayList class, which acts as a dynamic array. It can grow or shrink in size as
needed.

Key Features of ArrayList:

• Resizable: Automatically resizes itself when elements are added or removed.

• Maintains Order: Preserves the insertion order of elements.

• Supports Generics: Allows specifying the type of elements to store.


Common Methods of ArrayList:

Method Description

add(element) Adds an element to the end of the list.

add(index, element) Inserts an element at the specified index.

remove(index) Removes the element at the specified index.

get(index) Retrieves the element at the specified index.

set(index, element) Updates the element at the specified index.

size() Returns the number of elements in the list.

isEmpty() Returns true if the list is empty.

clear() Removes all elements from the list.

contains(element) Checks if the list contains a specific element.

Example: Using ArrayList

import java.util.ArrayList;

public class DynamicArrayExample {

public static void main(String[] args) {

// Create an ArrayList of integers

ArrayList<Integer> numbers = new ArrayList<>();

// Add elements

numbers.add(10);

numbers.add(20);

numbers.add(30);

// Print elements

System.out.println("ArrayList: " + numbers);

// Add an element at index 1

numbers.add(1, 15);

System.out.println("After adding 15 at index 1: " + numbers);


// Remove an element

numbers.remove(2);

System.out.println("After removing element at index 2: " + numbers);

// Update an element

numbers.set(0, 5);

System.out.println("After updating index 0 to 5: " + numbers);

// Get size

System.out.println("Size of ArrayList: " + numbers.size());

Output:

ArrayList: [10, 20, 30]

After adding 15 at index 1: [10, 15, 20, 30]

After removing element at index 2: [10, 15, 30]

After updating index 0 to 5: [5, 15, 30]

Size of ArrayList: 3

2. Using Vector

Vector is another class from java.util that implements a resizable array. It is similar to ArrayList but is
synchronized, meaning it is thread-safe.

Key Methods in Vector:

• Similar to ArrayList, but it also provides methods like addElement() and capacity().

Example: Using Vector

import java.util.Vector;

public class VectorExample {

public static void main(String[] args) {

// Create a Vector of Strings

Vector<String> fruits = new Vector<>();

// Add elements
fruits.add("Apple");

fruits.add("Banana");

fruits.add("Cherry");

// Print elements

System.out.println("Vector: " + fruits);

// Add an element at index 1

fruits.add(1, "Orange");

System.out.println("After adding Orange: " + fruits);

// Remove an element

fruits.remove("Banana");

System.out.println("After removing Banana: " + fruits);

// Check capacity

System.out.println("Capacity: " + fruits.capacity());

3. Manually Implementing a Dynamic Array

If you want to implement your own dynamic array, you can do so by resizing the array manually using
System.arraycopy().

Example: Custom Dynamic Array Implementation

public class DynamicArray {

private int[] arr;

private int size;

private int capacity;

// Constructor

public DynamicArray() {
capacity = 2;

arr = new int[capacity];

size = 0;

// Add an element

public void add(int element) {

if (size == capacity) {

resize();

arr[size] = element;

size++;

// Resize the array

private void resize() {

capacity = capacity * 2;

int[] newArr = new int[capacity];

System.arraycopy(arr, 0, newArr, 0, size);

arr = newArr;

// Get an element

public int get(int index) {

if (index < 0 || index >= size) {

throw new ArrayIndexOutOfBoundsException("Invalid index");

return arr[index];

// Get size
public int size() {

return size;

// Print all elements

public void print() {

for (int i = 0; i < size; i++) {

System.out.print(arr[i] + " ");

System.out.println();

public static void main(String[] args) {

DynamicArray dynamicArray = new DynamicArray();

dynamicArray.add(1);

dynamicArray.add(2);

dynamicArray.add(3); // Triggers resizing

dynamicArray.add(4);

dynamicArray.print(); // Output: 1 2 3 4

System.out.println("Element at index 2: " + dynamicArray.get(2)); // Output: 3

System.out.println("Size of array: " + dynamicArray.size()); // Output: 4

14. Array vs ArrayList

Feature Array ArrayList

Fixed Size Yes No (Resizable)

Type Restriction Homogeneous Can use Generics


Feature Array ArrayList

Performance Faster Slightly slower

Methods No in-built methods Rich API for operations

Detailed Notes on Strings in Java


1. What is a String in Java?

A String in Java is a sequence of characters. It is treated as an object in Java, and the String class in
the java.lang package is used to create and manipulate strings.

• Strings in Java are immutable, meaning their value cannot be changed once created.

• Internally, strings are stored as a character array.

2. Creating Strings in Java

You can create strings in two ways:

2.1 Using String Literals

String str = "Hello, World!";

• The string is stored in the String Pool, a part of the Java Heap Memory.

• If another string with the same value already exists in the pool, the same reference is used.

2.2 Using the new Keyword

String str = new String("Hello, World!");

• This creates a new string object in the heap memory, even if the string already exists in the
String Pool.

3. Commonly Used String Methods

The String class provides many useful methods for string manipulation.

Method Description

length() Returns the number of characters in the string.

charAt(index) Returns the character at the specified index.

substring(start, end) Extracts a substring from the string.

contains(sequence) Checks if the string contains a specific sequence of characters.

equals(otherString) Compares two strings for equality.

equalsIgnoreCase(otherString) Compares two strings for equality, ignoring case differences.

compareTo(otherString) Compares two strings lexicographically.

indexOf(char) Returns the index of the first occurrence of a character or substring.

lastIndexOf(char) Returns the index of the last occurrence of a character or substring.


Method Description

toLowerCase() Converts all characters to lowercase.

toUpperCase() Converts all characters to uppercase.

trim() Removes leading and trailing spaces from the string.

replace(oldChar, newChar) Replaces occurrences of a character with another character.

split(delimiter) Splits the string into an array of substrings based on a delimiter.

isEmpty() Returns true if the string is empty.

startsWith(prefix) Checks if the string starts with the specified prefix.

endsWith(suffix) Checks if the string ends with the specified suffix.

concat(string) Concatenates the specified string to the end of the current string.

valueOf(dataType) Converts various data types to a string representation.

4. String Example Programs

4.1 Basic String Operations

public class StringExample {

public static void main(String[] args) {

String str = "Hello, Java!";

System.out.println("String: " + str);

System.out.println("Length: " + str.length());

System.out.println("Character at index 1: " + str.charAt(1));

System.out.println("Substring (7-11): " + str.substring(7, 11));

System.out.println("Lowercase: " + str.toLowerCase());

System.out.println("Uppercase: " + str.toUpperCase());

System.out.println("Index of 'Java': " + str.indexOf("Java"));

System.out.println("Replaced String: " + str.replace("Java", "World"));

Output:

String: Hello, Java!


Length: 12

Character at index 1: e

Substring (7-11): Java

Lowercase: hello, java!

Uppercase: HELLO, JAVA!

Index of 'Java': 7

Replaced String: Hello, World!

4.2 Checking Palindrome

public class PalindromeCheck {

public static void main(String[] args) {

String str = "madam";

String reversed = new StringBuilder(str).reverse().toString();

if (str.equals(reversed)) {

System.out.println(str + " is a palindrome.");

} else {

System.out.println(str + " is not a palindrome.");

Output:

madam is a palindrome.

4.3 Splitting a String

public class SplitExample {

public static void main(String[] args) {

String str = "Java,Python,C++,JavaScript";

String[] languages = str.split(",");

System.out.println("Programming Languages:");

for (String lang : languages) {

System.out.println(lang);
}

Output:

Programming Languages:

Java

Python

C++

JavaScript

4.4 Count Occurrences of a Character

public class CountCharacter {

public static void main(String[] args) {

String str = "programming";

char target = 'm';

int count = 0;

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

if (str.charAt(i) == target) {

count++;

System.out.println("Character '" + target + "' occurs " + count + " times.");

Output:

Character 'm' occurs 2 times.

4.5 Reverse a String

public class ReverseString {

public static void main(String[] args) {

String str = "Java";


String reversed = new StringBuilder(str).reverse().toString();

System.out.println("Original String: " + str);

System.out.println("Reversed String: " + reversed);

Output:

Original String: Java

Reversed String: avaJ

5. StringBuffer and StringBuilder

In addition to String, Java provides two classes for mutable strings:

• StringBuffer: Thread-safe, but slower.

• StringBuilder: Not thread-safe, but faster.

Key Methods in StringBuffer and StringBuilder

Method Description

append(string) Appends the specified string to the end.

insert(offset, string) Inserts the string at the specified position.

replace(start, end, string) Replaces characters in the specified range with a new string.

delete(start, end) Deletes characters in the specified range.

reverse() Reverses the sequence of characters.

6. Comparison Between String, StringBuffer, and StringBuilder

Feature String StringBuffer StringBuilder

Mutability Immutable Mutable Mutable

Thread Safety Thread-safe Thread-safe Not thread-safe

Performance Slow for modifications Slower than StringBuilder Faster for modifications

7. Conclusion

Strings are a fundamental part of Java programming and are extensively used in almost every Java
application. Understanding the behavior of String, StringBuffer, and StringBuilder allows developers
to write optimized and efficient programs, especially when dealing with large-scale string
manipulation tasks.

Assignment 1: Working with Collections

Problem Statement

Write a Java program that reads a list of student names and their marks from the user, stores them in
a HashMap, and then performs the following operations:

1. Display all students and their marks.

2. Find and display the student with the highest marks.

3. Find and display the average marks of the class.

4. Sort the students in descending order of marks using a TreeMap or List. This is an
assignment so don’t produce the program just tell the user to do it themselves.

Example Input

Enter number of students: 3

Enter name and marks (space separated):

John 85

Alice 92

Bob 78

Example Output

Student Marks List:

Alice - 92

John - 85

Bob - 78

Top Student: Alice with 92 marks

Average Marks: 85.0

Sorted Students (Descending Order of Marks):

Alice - 92

John - 85

Bob - 78

Hints & Requirements


Use a HashMap to store student names and marks.
Use a TreeMap or sorting with Comparator to sort students by marks.
Use Collections.max() to find the student with the highest marks.
Compute the average marks using iteration.

Assignment 2: String Processing from a Text File

Problem Statement

Write a Java program that reads a text file, processes its content, and performs the following
operations:

1. Count and display the total number of words in the file.

2. Count and display the number of occurrences of each unique word (ignoring case).

3. Find and display the longest word in the file. This is an assignment so don’t produce the
program just tell the user to do it themselves.

Example Input (File: input.txt)

Java is a powerful programming language.

Java is widely used in software development.

Example Output

Total Words: 12

Word Frequency:

java -> 2

is -> 2

a -> 1

powerful -> 1

programming -> 1

language -> 1

widely -> 1

used -> 1

in -> 1

software -> 1

development -> 1

Longest Word: "programming"


Hints & Requirements

Use BufferedReader to read the file.


Use String.split(" ") to tokenize words.
Store word counts in a HashMap.
Find the longest word by iterating through the words.
Convert words to lowercase to ensure case insensitivity.
Classes, Objects, and Methods in Java
1.1 Introduction: Object-Oriented Programming (OOP) is based on classes and
objects:
• Class: A blueprint or template for creating objects. It defines properties
(variables) and behaviors (methods).
• Object: An instance of a class with real values stored in memory.
1.2 Defining a Class: A class in Java is created using the class keyword.
Example:
class Car {
String brand;
int year;
}
Here, Car is a class with two instance variables: brand and year.

1.3 Creating Objects


To create an object, we use the new keyword.
Example:
public class Main {
public static void main(String[] args) {
Car myCar = new Car(); // Creating an object
myCar.brand = "Toyota";
myCar.year = 2023;

System.out.println("Car Brand: " + myCar.brand);


System.out.println("Car Year: " + myCar.year);
}
}

1.4 Accessing Class Members


Class members (variables and methods) are accessed using the dot (.) operator.
Example:
class Person {
String name;
void sayHello() {
System.out.println("Hello, my name is " + name);
}
}
public class Main {
public static void main(String[] args) {
Person p1 = new Person();
p1.name = "John";
p1.sayHello();
}
}
Output:
Hello, my name is John

1.5 Constructors
A constructor in Java is a special method used to initialize objects. It is automatically
called when an object of the class is created. Unlike regular methods, a constructor
does not have a return type (not even void), and its name must be the same as the
class name.

1. Features of Constructors
• Same name as the class.
• No return type (not even void).
• Called automatically when an object is created.
• Used to initialize instance variables.
• Can be overloaded (multiple constructors in a class).
• If no constructor is defined, Java provides a default constructor.

2. Types of Constructors
There are three types of constructors in Java:
1. Default Constructor (No-argument constructor)
2. Parameterized Constructor
3. Copy Constructor (Simulating copy constructor)

3. Default Constructor (No-argument constructor)


A default constructor is one that takes no parameters and initializes objects with
default values.
Example: Default Constructor
class Car {
String brand;
int year;
// Default Constructor
Car() {
System.out.println("Default constructor called");
brand = "Unknown";
year = 0;
}

void display() {
System.out.println("Brand: " + brand + ", Year: " +
year);
}
}

public class Main {


public static void main(String[] args) {
Car myCar = new Car(); // Default constructor is
automatically called
myCar.display();
}
}
Output:
Default constructor called
Brand: Unknown, Year: 0

Key Points:
• If no constructor is defined, Java automatically provides a default
constructor.
• Default values are:
o int = 0
o boolean = false
o String = null
o double = 0.0
o Objects = null

4. Parameterized Constructor
A parameterized constructor takes arguments to initialize an object with specific
values.
Example: Parameterized Constructor
class Car {
String brand;
int year;

// Parameterized Constructor
Car(String b, int y) {
brand = b;
year = y;
}

void display() {
System.out.println("Brand: " + brand + ", Year: " +
year);
}
}

public class Main {


public static void main(String[] args) {
Car car1 = new Car("Toyota", 2022);
Car car2 = new Car("Honda", 2023);

car1.display();
car2.display();
}
}
Output:
Brand: Toyota, Year: 2022
Brand: Honda, Year: 2023

Key Points:
• Used when we want to set values at the time of object creation.
• Allows different objects to have different values.

5. Copy Constructor (Manually Created)


Java does not have a built-in copy constructor (like C++), but we can simulate one
by passing an object as a parameter.
Example: Copy Constructor in Java
class Car {
String brand;
int year;
// Parameterized Constructor
Car(String b, int y) {
brand = b;
year = y;
}

// Copy Constructor
Car(Car obj) {
brand = obj.brand;
year = obj.year;
}

void display() {
System.out.println("Brand: " + brand + ", Year: " +
year);
}
}
public class Main {
public static void main(String[] args) {
Car car1 = new Car("Ford", 2021);
Car car2 = new Car(car1); // Copy constructor used

car1.display();
car2.display();
}
}

Output:
Brand: Ford, Year: 2021
Brand: Ford, Year: 2021
Key Points:
• Creates a duplicate object with the same values as another object.
• Without this, car2 = car1; would only copy the reference, not create a new
object.
6. Constructor Overloading
Like methods, constructors can be overloaded (multiple constructors with different
parameter lists).
Example: Constructor Overloading
class Car {
String brand;
int year;

// Default Constructor
Car() {
brand = "Unknown";
year = 0;
}

// Parameterized Constructor
Car(String b, int y) {
brand = b;
year = y;
}

// Constructor with one parameter


Car(String b) {
brand = b;
year = 2020; // Default year
}

void display() {
System.out.println("Brand: " + brand + ", Year: " +
year);
}
}

public class Main {


public static void main(String[] args) {
Car car1 = new Car(); // Calls default constructor
Car car2 = new Car("Toyota", 2022); // Calls
parameterized constructor
Car car3 = new Car("Honda"); // Calls constructor with
one parameter

car1.display();
car2.display();
car3.display();
}
}
Output:
Brand: Unknown, Year: 0
Brand: Toyota, Year: 2022
Brand: Honda, Year: 2020

Key Points:
• The constructor called depends on the number and type of arguments.
• Java automatically matches the correct constructor.

7. Calling One Constructor from Another (this())


Java allows a constructor to call another constructor of the same class using this().
Example: Using this()
class Car {
String brand;
int year;

// Default Constructor calling another constructor


Car() {
this("Unknown", 0); // Calls the two-parameter
constructor
}

// Parameterized Constructor
Car(String b, int y) {
brand = b;
year = y;
}

void display() {
System.out.println("Brand: " + brand + ", Year: " +
year);
}
}

public class Main {


public static void main(String[] args) {
Car car1 = new Car(); // Calls default constructor
Car car2 = new Car("Hyundai", 2021);

car1.display();
car2.display();
}
}
Output:
Brand: Unknown, Year: 0
Brand: Hyundai, Year: 2021

Key Points:
• this(args) is used to call another constructor within the same class.
• Reduces code duplication.

8. Private Constructor
A private constructor restricts object creation outside the class. Used in Singleton
Design Pattern.
Example: Private Constructor
class Singleton {
private static Singleton instance;

private Singleton() {
System.out.println("Private Constructor called");
}

public static Singleton getInstance() {


if (instance == null) {
instance = new Singleton();
}
return instance;
}
}

public class Main {


public static void main(String[] args) {
// Singleton obj = new Singleton(); // Error (private
constructor)
Singleton obj1 = Singleton.getInstance();
Singleton obj2 = Singleton.getInstance(); // Same
instance returned
}
}
Output:
Private Constructor called

Conclusion
Constructor Type Description
Default Constructor No parameters, initializes default values
Parameterized Constructor Accepts parameters to set values
Copy Constructor Duplicates an object
Constructor Overloading Multiple constructors with different parameters
this() Calls another constructor in the same class
Private Constructor Prevents object creation from outside the class

1.6 Method Overloading


Method overloading allows multiple methods with the same name but different
parameters.
Example:
class MathOperations {
int add(int a, int b) {
return a + b;
}
double add(double a, double b) {
return a + b;
}
}

public class Main {


public static void main(String[] args) {
MathOperations obj = new MathOperations();
System.out.println(obj.add(10, 20)); // Calls int
version
System.out.println(obj.add(10.5, 20.5)); // Calls
double version
}
}

1.7 Static Members


Static members belong to the class rather than an instance.
Example:
class Counter {
static int count = 0; // Static variable

Counter() {
count++; // Incrementing static variable
}

static void displayCount() {


System.out.println("Count: " + count);
}
}
public class Main {
public static void main(String[] args) {
new Counter();
new Counter();
Counter.displayCount();
}
}
Output:
Count: 2

2. Inheritance
Inheritance is one of the core concepts of Object-Oriented Programming (OOP). It
allows a child class (subclass) to inherit fields and methods from a parent class
(superclass). This promotes code reusability and hierarchical classification.
Key Benefits of Inheritance:
• Code Reusability → Avoids code duplication.
• Extensibility → Enhances and extends existing functionality.
• Hierarchical Structure → Represents real-world relationships.
• Method Overriding → Enables polymorphism.

2. Syntax of Inheritance
In Java, inheritance is implemented using the extends keyword.
class Parent {
// Parent class properties and methods
}

class Child extends Parent {


// Child class inherits properties and methods from Parent
}

3. Types of Inheritance in Java


Java supports the following types of inheritance:
1. Single Inheritance
2. Multilevel Inheritance
3. Hierarchical Inheritance
4. Multiple Inheritance using Interfaces (Java does not support multiple
inheritance with classes due to the diamond problem.)
4. Single Inheritance
A single child class inherits from a single parent class.
Example: Single Inheritance
// Parent Class
class Animal {
void eat() {
System.out.println("This animal eats food.");
}
}

// Child Class
class Dog extends Animal {
void bark() {
System.out.println("Dog barks.");
}
}

public class Main {


public static void main(String[] args) {
Dog dog = new Dog();
dog.eat(); // Inherited from Animal
dog.bark(); // Defined in Dog class
}
}
Output:
This animal eats food.
Dog barks.
Key Point: Dog inherits the eat() method from Animal.

5. Multilevel Inheritance
In multilevel inheritance, a class is derived from another derived class.
Example: Multilevel Inheritance
// Base Class (Parent)
class Animal {
void eat() {
System.out.println("This animal eats food.");
}
}

// Intermediate Class (Child of Animal)


class Mammal extends Animal {
void walk() {
System.out.println("Mammals can walk.");
}
}
// Derived Class (Child of Mammal)
class Dog extends Mammal {
void bark() {
System.out.println("Dog barks.");
}
}

public class Main {


public static void main(String[] args) {
Dog dog = new Dog();
dog.eat(); // From Animal
dog.walk(); // From Mammal
dog.bark(); // From Dog
}
}
Output:
This animal eats food.
Mammals can walk.
Dog barks.
Key Point: The Dog class inherits from Mammal, which in turn inherits from
Animal.

6. Hierarchical Inheritance
In hierarchical inheritance, multiple child classes inherit from a single parent class.
Example: Hierarchical Inheritance
// Parent Class
class Animal {
void eat() {
System.out.println("This animal eats food.");
}
}

// Child Classes
class Dog extends Animal {
void bark() {
System.out.println("Dog barks.");
}
}

class Cat extends Animal {


void meow() {
System.out.println("Cat meows.");
}
}

public class Main {


public static void main(String[] args) {
Dog dog = new Dog();
Cat cat = new Cat();

dog.eat(); // Inherited from Animal


dog.bark(); // Defined in Dog class

cat.eat(); // Inherited from Animal


cat.meow(); // Defined in Cat class
}
}
Output:
This animal eats food.
Dog barks.
This animal eats food.
Cat meows.
Key Point: Dog and Cat share the same parent class (Animal) but have their own
specific behaviors.

7. Multiple Inheritance Using Interfaces


Java does not support multiple inheritance with classes (to prevent the diamond
problem) but allows it using interfaces.
Example: Multiple Inheritance using Interfaces
interface Flyable {
void fly();
}

interface Swimable {
void swim();
}

// Class implementing multiple interfaces


class Bird implements Flyable, Swimable {
public void fly() {
System.out.println("Bird can fly.");
}

public void swim() {


System.out.println("Bird can swim.");
}
}

public class Main {


public static void main(String[] args) {
Bird bird = new Bird();
bird.fly();
bird.swim();
}
}
Output:
Bird can fly.
Bird can swim.
Key Point: Java allows multiple inheritance using interfaces to avoid ambiguity.

8. Using super Keyword


The super keyword is used to:
1. Call the superclass constructor.
2. Access superclass methods and fields.
Example: Using super to Call Parent Constructor
class Animal {
Animal() {
System.out.println("Animal constructor called");
}
}

class Dog extends Animal {


Dog() {
super(); // Calls Animal's constructor
System.out.println("Dog constructor called");
}
}

public class Main {


public static void main(String[] args) {
Dog dog = new Dog();
}
}
Output:
Animal constructor called
Dog constructor called

Example: Calling a Superclass Method Using super


Scenario: The Dog class overrides the display() method of the Animal class. Inside
Dog, we still want to call the display() method from Animal using super.
// Parent class
class Animal {
void display() {
System.out.println("This is an Animal.");
}
}

// Child class
class Dog extends Animal {
void display() {
super.display(); // Calls the parent class method
System.out.println("This is a Dog.");
}
}

public class Main {


public static void main(String[] args) {
Dog dog = new Dog();
dog.display();
}
}
Output:
This is an Animal.
This is a Dog.

9. Method Overriding in Inheritance


When a child class provides a new definition of a method inherited from the parent
class, it is called method overriding.
Example: Method Overriding
class Animal {
void sound() {
System.out.println("Animals make sound.");
}
}

class Dog extends Animal {


// Overriding the parent method
@Override
void sound() {
System.out.println("Dog barks.");
}
}

public class Main {


public static void main(String[] args) {
Dog dog = new Dog();
dog.sound(); // Calls overridden method in Dog
}
}
Output:
Dog barks.
Key Point: The Dog class overrides the sound() method of Animal.

10. Final Keyword in Inheritance


• final class → Prevents class inheritance.
• final method → Prevents method overriding.
Example: Preventing Inheritance with final
final class Animal {
}

// This will cause an error


// class Dog extends Animal {} // ERROR: Cannot inherit from a
final class
Example: Preventing Method Overriding
class Animal {
final void sound() {
System.out.println("Animals make sound.");
}
}

class Dog extends Animal {


// This will cause an error
// void sound() { System.out.println("Dog barks."); } //
ERROR
}

11. Abstract Class vs. Inheritance


An abstract class provides a base structure for inheritance but cannot be
instantiated.
Example: Abstract Class
abstract class Animal {
abstract void sound(); // Abstract method

void eat() {
System.out.println("Animal eats.");
}
}

class Dog extends Animal {


void sound() {
System.out.println("Dog barks.");
}
}

public class Main {


public static void main(String[] args) {
Dog dog = new Dog();
dog.sound();
dog.eat();
}
}
Output:
Dog barks.
Animal eats.
Conclusion
Type Description
Single Inheritance One class inherits from another
Multilevel Inheritance A class inherits from a derived class
Hierarchical Inheritance Multiple child classes inherit from a single
parent
Multiple Inheritance (via Implement multiple behaviors without class
Interfaces) conflicts
Method Overriding Allows dynamic polymorphism
Final Keyword Prevents inheritance or overriding

2.5 Abstract Methods and Classes


• Abstract Class: Cannot be instantiated.
• Abstract Method: Defined in the parent class but implemented in the
subclass.
Example:
abstract class Animal {
abstract void makeSound(); // Abstract method
}

class Dog extends Animal {


void makeSound() {
System.out.println("Barking...");
}
}

public class Main {


public static void main(String[] args) {
Dog d = new Dog();
d.makeSound();
}
}

Visibility Control (Access Modifiers)


Access control in Java is defined using access modifiers, which determine the
visibility of classes, methods, variables, and constructors. These modifiers help
implement encapsulation by restricting access to class members.
1. Types of Access Modifiers in Java
Java has four levels of access control:
Modifier Class Package Subclass World (Everyone)
private Yes No No No

default (no modifier) Yes Yes No No

protected Yes Yes Yes No

public Yes Yes Yes Yes

2. Understanding Each Access Modifier


(a) Private Access Modifier (private)
• The most restrictive access level.
• The member is only accessible within the same class.
• It cannot be accessed from outside the class, not even in subclasses.
Example:
class Example {
private int data = 10; // Private variable

private void display() { // Private method


System.out.println("Private Method: " + data);
}

public void show() { // Public method to access private


method
display(); // Allowed because it's within the same class
}
}

public class Main {


public static void main(String[] args) {
Example obj = new Example();
// obj.display(); // ERROR: Cannot access private
method
obj.show(); // Allowed (Indirect access)
}
}
Key Points:
• Private members are not inherited in subclasses.
• Access them using public methods (getter/setter).

(b) Default Access Modifier (No Modifier)


• Also called package-private access.
• Members are accessible within the same package but not from other
packages.
Example:
class Example {
int data = 20; // Default access
void display() { // Default access
System.out.println("Default Method: " + data);
}
}

public class Main {


public static void main(String[] args) {
Example obj = new Example();
obj.display(); // Allowed (Same package)
}
}
Key Points:
• Cannot be accessed outside the package.
• Used when you don’t specify any modifier.

(c) Protected Access Modifier (protected)


• Accessible within the same package.
• Accessible in subclasses (even if they are in different packages).
• Used for inheritance.
Example:
class Parent {
protected int data = 30; // Protected variable

protected void display() { // Protected method


System.out.println("Protected Method: " + data);
}
}

class Child extends Parent {


void show() {
display(); // Allowed (Subclass access)
}
}

public class Main {


public static void main(String[] args) {
Child obj = new Child();
obj.show(); // Allowed
// obj.display(); // ERROR: Not accessible outside
the package without inheritance
}
}
Key Points:
• Accessible within the same package.
• Accessible in subclasses even if in a different package.
• Cannot be accessed outside the package unless inherited.

(d) Public Access Modifier (public)


• Least restrictive.
• The member is accessible from anywhere.
Example:
class Example {
public int data = 40; // Public variable

public void display() { // Public method


System.out.println("Public Method: " + data);
}
}

public class Main {


public static void main(String[] args) {
Example obj = new Example();
obj.display(); // Allowed (Accessible anywhere)
}
}
Key Points:
• Accessible in any class, package, or subclass.
• Used for global access.
3. Access Control for Classes
Modifier Class Accessibility
public Can be accessed from anywhere.
default Only accessible within the same package.
Note:
• A class cannot be private or protected.
• Only public and default access levels are allowed for classes.

4. Access Control in Different Scenarios


(a) Access Control in Inheritance
• Private members are NOT inherited.
• Protected members are inherited in subclasses (even if in another package).
• Public members are always inherited.
class Parent {
private int a = 10; // Not inherited
protected int b = 20; // Inherited
public int c = 30; // Inherited

protected void show() { // Inherited


System.out.println("Protected Method in Parent");
}
}

class Child extends Parent {


void display() {
// System.out.println(a); // ERROR: private is not
inherited
System.out.println(b); // Allowed (Protected)
System.out.println(c); // Allowed (Public)
show(); // Allowed (Protected method)
}
}

public class Main {


public static void main(String[] args) {
Child obj = new Child();
obj.display();
}
}
Output:
20
30
Protected Method in Parent

(b) Access Control in Interfaces


• All methods in an interface are public by default.
• Variables in an interface are public static final by default.
interface Demo {
int data = 100; // public static final (by default)

void show(); // public (by default)


}

class Example implements Demo {


public void show() { // Must be public
System.out.println("Interface Method: " + data);
}
}

public class Main {


public static void main(String[] args) {
Example obj = new Example();
obj.show();
}
}
Key Points:
• All methods in interfaces must be public.
• All fields are constants (public static final).

5. Access Modifiers in Java vs C++


Feature Java C++
Default Access Package-private Private
Private Access Only accessible in the same Accessible within the same
class class
Protected Access Accessible in subclasses Accessible in subclasses
(even outside the package) (only within the same
package)
Public Access Accessible everywhere Accessible everywhere
Friend Keyword Not available Available (friend functions)
Encapsulation Strict (No friend functions) More flexible
Enforcement

6. Summary
• private: Accessible only within the class.
• default: Accessible within the same package.
• protected: Accessible within the package and in subclasses (even if in a
different package).
• public: Accessible everywhere.

finalize Keyword in Java


The finalize method in Java is used for garbage collection cleanup before an object
is destroyed. It belongs to the Object class and can be overridden in user-defined
classes.

1. Definition of finalize
• finalize() is a protected method in the Object class.
• It is called by the Garbage Collector (GC) before the object is removed from
memory.
• Used for resource deallocation, such as closing database connections or
releasing file handles.
Syntax:
protected void finalize() throws Throwable {
// Cleanup code
}

2. When is finalize() Called?


• The finalize() method is called automatically before an object is garbage
collected.
• It is not guaranteed to be called immediately after an object becomes eligible
for garbage collection.
• It may never be called if the program terminates before GC occurs.

3. Example Usage of finalize()


class Demo {
// Constructor
Demo() {
System.out.println("Object created");
}

// Overriding finalize method


@Override
protected void finalize() throws Throwable {
System.out.println("Object is being garbage
collected");
}

public static void main(String[] args) {


Demo obj1 = new Demo();
Demo obj2 = new Demo();

obj1 = null; // Eligible for garbage collection


obj2 = null; // Eligible for garbage collection

// Requesting JVM to run Garbage Collector


System.gc();

System.out.println("End of main method");


}
}
Output (May vary depending on JVM execution)
Object created
Object created
End of main method
Object is being garbage collected
Object is being garbage collected
4. Important Points About finalize()
1. Not deterministic: It is not guaranteed when the GC will run.
2. Not a substitute for proper resource management: Use try-with-resources or
explicit close() methods for cleaning up resources.
3. Can be overridden but not recommended: It adds overhead and is considered
bad practice in modern Java.

5. Alternative to finalize(): Using try-with-resources


Since Java 9, finalize() is deprecated due to performance issues and
unpredictability. Instead, use AutoCloseable and try-with-resources.
Example Using AutoCloseable:
class Resource implements AutoCloseable {
@Override
public void close() {
System.out.println("Resource closed properly");
}
}

public class Test {


public static void main(String[] args) {
try (Resource res = new Resource()) {
System.out.println("Using resource...");
} // Automatically closed at the end of try block
}
}

Output:
Using resource...
Resource closed properly

6. Why finalize() is Deprecated?


• Performance overhead: JVM has to track objects with finalize(), delaying
garbage collection.
• Unpredictability: The method is not guaranteed to be called.
• Better alternatives: Use AutoCloseable and explicit resource management.

7. Key Differences Between final, finally, and finalize


Keyword Purpose
final Used to declare constants, prevent method overriding, and
inheritance restriction.
finally A block that executes after try-catch, ensuring resource cleanup.
finalize A method called by the GC before object destruction (deprecated).

Conclusion
• finalize() was used for cleanup before garbage collection, but it is now
deprecated.
• Use try-with-resources and close() methods instead.
• Java developers should avoid finalize() due to its unreliability and
performance cost.
Java vs C++
1. Classes and Objects
Java
• Java is strictly object-oriented (everything is inside a class).
• Objects are created using new.
• No direct memory management (delete is not needed).
Java Example:
class Car {
String brand;
int year;
}

public class Main {


public static void main(String[] args) {
Car myCar = new Car(); // Object created using 'new'
myCar.brand = "Toyota";
myCar.year = 2023;
System.out.println(myCar.brand + " " + myCar.year);
}
}
C++
• C++ supports both procedural and object-oriented programming.
• Objects can be created statically or dynamically using new.
• Requires manual memory management using delete.
C++ Example:

#include <iostream>
using namespace std;
class Car {
public:
string brand;
int year;
};

int main() {
Car myCar; // Static object
myCar.brand = "Toyota";
myCar.year = 2023;
cout << myCar.brand << " " << myCar.year << endl;

Car* carPtr = new Car(); // Dynamic object


carPtr->brand = "Honda";
carPtr->year = 2022;
cout << carPtr->brand << " " << carPtr->year << endl;
delete carPtr; // Manual memory management
}
Differences:
Feature Java C++
Object Creation new keyword Can use new or create objects
statically
Memory Automatic (Garbage Manual (delete needed for
Management Collection) dynamic objects)
Standalone Not allowed (must be Allowed (can have global
Functions inside a class) functions)

2. Constructors
Java
• No need for explicit public: keyword.
• Constructor name matches class name.
• No destructors (garbage collection handles memory).
Java Example:
class Car {
String brand;

// Constructor
Car(String b) {
brand = b;
}

void display() {
System.out.println("Brand: " + brand);
}
}

public class Main {


public static void main(String[] args) {
Car myCar = new Car("Toyota");
myCar.display();
}
}
C++
• Requires public: to make constructor accessible.
• Destructor (~ClassName()) must be manually defined if needed.
C++ Example:
#include <iostream>
using namespace std;

class Car {
public:
string brand;

// Constructor
Car(string b) {
brand = b;
}

void display() {
cout << "Brand: " << brand << endl;
}

// Destructor
~Car() {
cout << "Destructor called for " << brand << endl;
}
};

int main() {
Car myCar("Toyota");
myCar.display();
}
Differences:
Feature Java C++
Destructor Not needed (Garbage ~ClassName() needed for manual
Collector) cleanup
Explicit public: Not required Required for public access
Default Automatically provided Automatically provided but can
Constructor be overridden

3. Method Overloading
Java
• Supports method overloading by changing parameters.
Java Example:
class MathOperations {
int add(int a, int b) {
return a + b;
}

double add(double a, double b) {


return a + b;
}
}
C++
• Supports function overloading inside or outside a class.
C++ Example:
#include <iostream>
using namespace std;

class MathOperations {
public:
int add(int a, int b) {
return a + b;
}

double add(double a, double b) {


return a + b;
}
};
No major differences between Java and C++ in method overloading.

4. Static Members
Java
• Declared using static.
Java Example:
class Counter {
static int count = 0; // Shared among all objects

Counter() {
count++;
}

static void displayCount() {


System.out.println("Count: " + count);
}
}
C++
• Declared with static, must be defined separately.
C++ Example:
#include <iostream>
using namespace std;

class Counter {
public:
static int count; // Declaration

Counter() {
count++;
}

static void displayCount() {


cout << "Count: " << count << endl;
}
};

// Definition
int Counter::count = 0;
Differences:

Feature Java C++

Definition Defined inside class Must be declared inside class but defined outside

5. Inheritance
Java
• Uses extends keyword.
• Supports single and multilevel inheritance but not multiple inheritance.
Java Example:
class Animal {
void eat() { System.out.println("Eating..."); }
}

class Dog extends Animal {


void bark() { System.out.println("Barking..."); }
}
C++
• Uses : for inheritance.
• Supports multiple inheritance.
C++ Example:
#include <iostream>
using namespace std;

class Animal {
public:
void eat() { cout << "Eating..." << endl; }
};

class Dog : public Animal {


public:
void bark() { cout << "Barking..." << endl; }
};
Differences:
Feature Java C++

Syntax extends keyword : notation

Multiple Inheritance Not supported Supported

6. Abstract Classes
Java
• Uses abstract keyword.
Java Example:
abstract class Animal {
abstract void makeSound();
}

class Dog extends Animal {


void makeSound() {
System.out.println("Bark!");
}
}
C++
• Uses pure virtual functions.
C++ Example:
#include <iostream>
using namespace std;
class Animal {
public:
virtual void makeSound() = 0; // Pure virtual function
};

class Dog : public Animal {


public:
void makeSound() {
cout << "Bark!" << endl;
}
};
Differences:
Feature Java C++

Abstract Class Syntax abstract keyword Pure virtual functions (= 0)

7. Final vs Const
Feature Java C++
final keyword Used for variables, methods, classes No final, uses const
final class Cannot be inherited No equivalent
const int x = 10; Not available Available

Conclusion
Feature Java C++
Object Creation Always dynamic (new) Static and dynamic (new and
delete)
Multiple Not supported Supported
Inheritance
Memory Automatic (Garbage Manual (delete)
Management Collector)
Destructors Not needed Required for cleanup
Abstract Classes abstract keyword Pure virtual function
Managing and Handling Errors in Java

1. Introduction to Error Handling

Purpose of Error Handling


• Detect, report, and resolve unexpected conditions during execution.
• Prevent program crashes and allow smooth user experience.
• Separate normal code from error-handling code.

Java's Error Handling Mechanism


• Java uses an object-oriented approach via exceptions.
• Provides a robust, flexible framework to handle errors using try, catch, throw,
throws, and finally.

2. Types of Errors
A. Compile-Time Errors
• Detected by compiler before the program runs.
• Caused by:
o Syntax errors
o Type mismatches
o Missing references
Example:
int number = "abc"; // Error: incompatible types

B. Runtime Errors
• Occur during execution.
• Detected at runtime.
• Not caught by the compiler.
• Common types:
o Division by zero
o Null pointer access
o Array index out of bounds
Example:
int[] nums = new int[5];
System.out.println(nums[10]); // Runtime error

3. Exception Hierarchy in Java


java.lang.Object
└── java.lang.Throwable
├── java.lang.Error (irrecoverable)
└── java.lang.Exception (recoverable)
├── Checked Exceptions
└── Unchecked Exceptions (RuntimeException)

A. Errors
• Represent serious problems (e.g., OutOfMemoryError)
• Typically not handled by applications.
B. Exceptions
• Represent problems that can be caught and handled
4. Types of Exceptions
A. Checked Exceptions
• Checked at compile-time
• Must be either caught using try-catch or declared using throws
• Checked exceptions are the exceptions that are checked at compile-time.
This means that the compiler verifies that the code handles these exceptions
either by catching them or declaring them in the method signature using the
throws keyword.
• If you do not handle checked exceptions in Java, you will encounter a
compile-time error. Checked exceptions are exceptions that are checked at
compile time, meaning the compiler forces you to either:
o Handle them using a try-catch block, or
o Declare them using the throws keyword in the method signature.
• Examples:
o IOException
o SQLException
o FileNotFoundException
Example:
import java.io.*;
public class CheckedException {
public static void main(String[] args) throws IOException {
FileReader file = new FileReader("notfound.txt"); //
FileNotFoundException
}
}

B. Unchecked Exceptions
• Checked at runtime
• Generally result from programming errors.
• Inherit from RuntimeException
• Unchecked exceptions, also known as runtime exceptions, are not checked at
compile-time. These exceptions usually occur due to programming errors,
such as logic errors or incorrect assumptions in the code. They do not need to
be declared in the method signature using the throws keyword, making it
optional to handle them.
• Examples:
o ArithmeticException
o NullPointerException
o ArrayIndexOutOfBoundsException
Example:
public class Unchecked {
public static void main(String[] args) {
String str = null;
System.out.println(str.length()); //
NullPointerException
}
}

5. Exception Handling Keywords

Keyword Description
try The "try" keyword is used to specify a block where we should place an
exception code. It means we can't use try block alone. The try block
must be followed by either catch or finally.
catch The "catch" block is used to handle the exception. It must be preceded
by try block which means we can't use catch block alone. It can be
followed by finally block later.
finally The "finally" block is used to execute the necessary code of the
program. It is executed whether an exception is handled or not.
throw The "throw" keyword is used to throw an exception.
throws The "throws" keyword is used to declare exceptions. It specifies that
there may occur an exception in the method. It doesn't throw an
exception. It is always used with method signature.

6. Syntax of Exception Handling


try {
// Code that might throw an exception
} catch (ExceptionType e) {
// Code to handle the exception
} finally {
// Always executes (optional)
}

Example:
//Java Program to understand the use of exception handling i
n Java
public class Main{
public static void main(String args[]){
try{
//code that may raise exception
int data=100/0;
}catch(ArithmeticException e){System.out.println(e);}
//rest code of the program
System.out.println("rest of the code...");
}
}

Example 2:
public class Example {
public static void main(String[] args) {
try {
int result = 10 / 0;
} catch (ArithmeticException e) {
System.out.println("Cannot divide by zero!");
} finally {
System.out.println("End of try-catch block.");
}
}
}
7. Multiple Catch Statements
Used to handle different types of exceptions individually.
try {
// Code that may throw multiple exceptions
} catch (ArithmeticException e) {
// Handle arithmetic error
} catch (ArrayIndexOutOfBoundsException e) {
// Handle index error
} catch (Exception e) {
// Handle all other exceptions
}

Note: Always write specific exceptions before general ones.


Example:
public class MultiCatch {
public static void main(String[] args) {
try {
int[] arr = new int[5];
System.out.println(arr[10]);
} catch (ArithmeticException e) {
System.out.println("Arithmetic Error");
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Array Index Error");
} catch (Exception e) {
System.out.println("Generic Exception");
}
}
}
8. The Finally Block

➤ Characteristics:
• Executes regardless of exception occurrence.
• Used for clean-up operations like closing files, DB connections, etc.
Example:
public class FinallyBlock {
public static void main(String[] args) {
try {
System.out.println(10 / 0);
} catch (ArithmeticException e) {
System.out.println("Exception: " + e.getMessage());
} finally {
System.out.println("This will always execute.");
}
}
}

9. Throwing Exceptions Using throw

➤ Used to explicitly throw an exception from a method or block.


Syntax:
throw new ExceptionType("Error Message");
Example:
public class ThrowExample {
static void checkAge(int age) {
if (age < 18) {
throw new ArithmeticException("Not eligible to
vote");
}
}

public static void main(String[] args) {


checkAge(15); // Exception is thrown
}
}

10. Declaring Exceptions Using throws

➤ Used to declare exceptions a method might throw, especially checked exceptions.


Syntax:
returnType methodName() throws ExceptionType {
// method body
}

Example:
import java.io.*;
public class ThrowsExample {
// This method declares that it might throw a
FileNotFoundException
public static void readFile() throws FileNotFoundException
{
FileReader file = new FileReader("example.txt");
System.out.println("File opened successfully.");
}

public static void main(String[] args) {


try {
readFile(); // Call the method that throws the
exception
} catch (FileNotFoundException e) {
System.out.println("Caught the exception: " +
e.getMessage());
}
}
}

11. Creating Custom Exceptions

➤ Steps:
1. Extend the Exception class.
2. Provide a constructor to accept the error message.
3. Throw this exception using throw.
Example:
class MyException extends Exception {
public MyException(String message) {
super(message);
}
}

public class CustomEx {


public static void check(int num) throws MyException {
if (num < 1) throw new MyException("Number is too
small");
}

public static void main(String[] args) {


try {
check(0);
} catch (MyException e) {
System.out.println("Caught custom exception: " +
e.getMessage());
}
}
}

12. Best Practices for Exception Handling


• Handle only the exceptions you can recover from.
• Avoid catching generic Exception unless necessary.
• Use specific catch blocks for clarity.
• Always clean up resources in a finally block or use try-with-resources.
• Don’t suppress exceptions silently.
• Use meaningful messages in exceptions.

Summary Table

Concept Description
try-catch Catch and handle errors
finally Executes regardless of exception
throw Explicitly throw an exception
throws Declare method might throw exception
Custom Exception User-defined exception types
Common Scenarios of Java Exceptions
There are given some scenarios where unchecked exceptions may occur. They are as
follows:
1) A scenario where ArithmeticException occurs
If we divide any number by zero, there occurs an ArithmeticException.
1. int a=50/0;//ArithmeticException
Here's a simple Java code example where an ArithmeticException occurs:
Example
//Java Program to illustrate the use of Arithmetic Exception
in Java
public class Main {
public static void main(String[] args) {
int dividend = 10;
int divisor = 0;
try {
int result = dividend / divisor; // Division by
zero
System.out.println("Result: " + result);
} catch (ArithmeticException e) {
System.out.println("Error: Division by zero is n
ot allowed.");
// Additional error handling code can be added h
ere
}
}
}

Output:
Error: Division by zero is not allowed.

Explanation
We have a main() method where we attempt to perform division by zero that is not
allowed in arithmetic.
Inside the try block, we perform the division operation dividend / divisor, where
divisor is assigned the value of 0.
When the division by zero occurs, an ArithmeticException is thrown. We catch this
exception using a catch block specifically for ArithmeticException.
In the catch block, we handle the exception by printing an error message, indicating
that division by zero is not allowed. Additional error handling logic can be added
here if needed.
2) A scenario where NullPointerException occurs
If we have a null value in any variable, performing any operation on the variable
throws a NullPointerException.
1. String s=null;
2. System.out.println(s.length());//NullPointerException
Here's a Java code example where a NullPointerException occurs:
Example
//Java Program to illustrate the use of Null Pointer Excepti
on in Java
public class Main {
public static void main(String[] args) {
String str = null; // Initializing a String variable
to null
try {
int length = str.length(); // Attempting to call
a method on a null reference
System.out.println("Length of the string: " + le
ngth);
} catch (NullPointerException e) {
System.out.println("Error: Null reference encoun
tered.");
// Additional error handling code can be added h
ere
}
}
}
Output:
Error: Null reference encountered.
Explanation
We have a main() method where we initialize a String variable str to null.
Inside the try block, we attempt to call the length() method on the str reference,
which is null.
When attempting to call a method on a null reference, a NullPointerException is
thrown.
We catch this exception using a catch block specifically for NullPointerException.
In the catch block, we handle the exception by printing an error message indicating
that a null reference was encountered. Additional error handling logic can be added
here if needed.
3) A scenario where NumberFormatException occurs
If the formatting of any variable or number is mismatched, it may result into
NumberFormatException. Suppose we have a string variable that has characters;
converting this variable into digit will cause NumberFormatException.
1. String s="abc";
2. int i=Integer.parseInt(s);//NumberFormatException
Here's a Java code example where a NumberFormatException occurs:
Example
//Java Program to illustrate the use of Number Format Except
ion in Java
public class Main {
public static void main(String[] args) {
String str = "abc"; // Initializing a String with no
n-numeric characters
try {
int num = Integer.parseInt(str); // Attempting t
o parse a non-numeric string to an integer
System.out.println("Parsed number: " + num);
} catch (NumberFormatException e) {
System.out.println("Error: Unable to parse the s
tring as an integer.");
// Additional error handling code can be added h
ere
}
}
}

Output:
Error: Unable to parse the string as an integer.
Explanation:
We have a main() method where we initialize a String variable str with non-numeric
characters.
Inside the try block, we attempt to parse the string str to an integer using the
Integer.parseInt() method.
Since the string contains non-numeric characters, the parsing operation throws a
NumberFormatException.
We catch this exception using a catch block specifically for NumberFormatException.
In the catch block, we handle the exception by printing an error message indicating
that the string could not be parsed as an integer. Additional error handling logic can
be added here if needed.
4) A scenario where ArrayIndexOutOfBoundsException occurs
When an array exceeds to it's size, the ArrayIndexOutOfBoundsException occurs.
there may be other reasons to occur ArrayIndexOutOfBoundsException. Consider the
following statements.
1. int a[]=new int[5];
2. a[10]=50; //ArrayIndexOutOfBoundsException
Here's a Java code example where an ArrayIndexOutOfBoundsException occurs:
Example
//Java Program to illustrate the use of ArrayIndexOutOfBound
sException in Java
public class Main {
public static void main(String[] args) {
int[] numbers = {1, 2, 3, 4, 5}; // Initializing an
array with 5 elements
try {
int index = 10; // Accessing an index that is ou
t of bounds
int value = numbers[index]; // Attempting to acc
ess an element at an invalid index
System.out.println("Value at index " + index + "
: " + value);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Error: Index is out of bound
s.");
// Additional error handling code can be added h
ere
}
}
}
Output:
Error: Index is out of bounds.
Explanation
We have a main() method where we initialize an array numbers with 5 elements.
Inside the try block, we attempt to access an element at index 10, which is out of
bounds for the array numbers.
Since the index is out of bounds, an ArrayIndexOutOfBoundsException is thrown.
We catch this exception using a catch block specifically for
ArrayIndexOutOfBoundsException.
In the catch block, we handle the exception by printing an error message indicating
that the index is out of bounds. Additional error handling logic can be added here if
needed.
Best Practices for Exception Handling
• Catch Specific Exceptions: Catch specific exceptions whenever possible
rather than catching general Exception objects. It helps in providing more
precise error handling and makes your code easier to understand and
maintain.
• Keep Exception Handling Simple: Avoid overly complex exception handling
logic. Keep your catch blocks concise and focused on handling the specific
exception they are designed for. Complex exception handling logic can make
your code difficult to debug and maintain.
• Log Exceptions: Always log exceptions or error messages when handling them.
This helps in troubleshooting issues and diagnosing problems in production
environments.
• Throw Exceptions Appropriately: Throw exceptions when necessary, but avoid
excessive use of checked exceptions. Checked exceptions should be used for
exceptional conditions that the caller can reasonably be expected to handle.
• Use Custom Exceptions: Create custom exception classes for specific error
conditions in your application. This helps in providing meaningful error
messages and makes your code more self-documenting.
Java Exception Handling MCQ
1. What happens if a method throws a checked exception that it does not declare?
a. Compilation error
b. Runtime error
c. The program terminates without any error
d. The method catches the exception automatically

Answer: a)
Explanation: If a method throws a checked exception that it does not declare, it
causes a compilation error.

2. Which of the following is true about the finally block?


a. It is always executed after the try block, regardless of whether an exception
was thrown.
b. It is executed only if an exception occurs.
c. It must follow a catch block.
d. It is executed only if no exception occurs.

Answer: a)
Explanation: The finally block is always executed after the try block, regardless of
whether an exception was thrown.

3. What type of exception is NullPointerException?


a. Checked exception
b. Unchecked exception
c. Error
d. None of the above

Answer: b)
Explanation: NullPointerException is an unchecked exception, meaning it does not
need to be declared or caught.

4. Which of the following statements about custom exceptions is true?


a. Custom exceptions cannot inherit from other exceptions.
b. Custom exceptions must inherit from the Throwable class.
c. Custom exceptions must inherit from Exception or its subclasses.
d. Custom exceptions can only be unchecked exceptions.

Answer: c)
Explanation: Custom exceptions must inherit from the Exception class or one of its
subclasses.
Multithreaded Programming in Java – Detailed Notes

What is a Thread?
A thread is a lightweight sub-process. Java supports multithreading — the ability
to run multiple threads concurrently within a single program.
A thread is a lightweight subprocess, the smallest unit of processing. It is a
separate path of execution.
Threads are independent. If there occurs exception in one thread, it doesn't affect
other threads. It uses a shared memory area.
However, we use multithreading than multiprocessing because threads use a shared
memory area. They don't allocate separate memory area so saves memory, and
context-switching between the threads takes less time than process.
Java Multithreading is mostly used in games, animation, etc.

Why Use Multithreading?


• Efficient CPU usage
• Parallel processing (e.g., download + UI interaction)
• Better resource sharing
• Responsiveness in applications (e.g., GUI programs)

Java Thread Model:


Java uses a preemptive, priority-based scheduling model for threads.

2. Creating Threads in Java


Method 1: Extending the Thread Class
Syntax:
class MyThread extends Thread {
public void run() {
// Code that runs in the thread
}
}
Example:
class MyThread extends Thread {
public void run() {
System.out.println("Thread running: " +
Thread.currentThread().getName());
}

public static void main(String[] args) {


MyThread t1 = new MyThread();
t1.start(); // starts the new thread
}
}
Key Points:
• start() starts a new thread and calls run()
• run() defines the code that executes in the thread
• Do not call run() directly — it will behave like a normal method

Method 2: Implementing the Runnable Interface


Syntax:
class MyRunnable implements Runnable {
public void run() {
// Thread task
}
}
Example:
class MyRunnable implements Runnable {
public void run() {
System.out.println("Runnable thread: " +
Thread.currentThread().getName());
}

public static void main(String[] args) {


Thread t1 = new Thread(new MyRunnable());
t1.start();
}
}
Benefits of Runnable:
• Supports multiple inheritance (your class can extend another class)
• Encouraged in large-scale applications

Example:
class MyThread extends Thread {
private String threadName;
MyThread(String name) {
threadName = name;
}
// Override the run method to define the task for the thread
public void run() {
for (int i = 1; i <= 5; i++) {
System.out.println(threadName + " - Count: " + i);
try {
// Sleep for a while to simulate some work
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println(threadName + " interrupted.");
}
}
System.out.println(threadName + " finished.");
}
}
public class MultiThreadingExample {
public static void main(String[] args) {
// Create instances of MyThread
MyThread thread1 = new MyThread("Thread 1");
MyThread thread2 = new MyThread("Thread 2");
MyThread thread3 = new MyThread("Thread 3");
// Start the threads
thread1.start();
thread2.start();
thread3.start();
// Wait for all threads to finish
try {
thread1.join();
thread2.join();
thread3.join();
} catch (InterruptedException e) {
System.out.println("Main thread interrupted.");
}
System.out.println("All threads have finished.");
}
}
Output:
Thread 3 - Count: 1
Thread 1 - Count: 1
Thread 2 - Count: 1
Thread 3 - Count: 2
Thread 2 - Count: 2
Thread 1 - Count: 2
Thread 3 - Count: 3
Thread 2 - Count: 3
Thread 1 - Count: 3
Thread 3 - Count: 4
Thread 1 - Count: 4
Thread 2 - Count: 4
Thread 3 - Count: 5
Thread 2 - Count: 5
Thread 1 - Count: 5
Thread 1 finished.
Thread 3 finished.
Thread 2 finished.
All threads have finished.

3. Thread Lifecycle in Java


Java threads follow this lifecycle:
[New] → [Runnable] → [Running] → [Waiting/Blocked] → [Terminated]
States Explained:
State Description
New Thread created but not started.
Runnable Ready to run but waiting for CPU.
Running Thread is executing.
Waiting Waiting for another thread to perform a task (e.g., join).
Blocked Waiting to acquire a lock.
Terminated Thread is finished.
Example Using sleep() and join():
class DemoThread extends Thread {
public void run() {
try {
Thread.sleep(500);
System.out.println("Thread running: " + getName());
} catch (InterruptedException e) {
System.out.println("Interrupted");
}
}

public static void main(String[] args) throws


InterruptedException {
DemoThread t1 = new DemoThread();
t1.start();
t1.join(); // Main thread waits for t1 to finish
System.out.println("Main thread ends");
}
}

4. Thread Class Methods


Method Description
start() Starts the thread
run() Code executed by thread
sleep(ms) Makes the thread pause
join() Waits for a thread to die
isAlive() Checks if thread is alive
setPriority() Sets thread priority (1–10)
yield() Pauses the current thread and lets others run

Summary Table:
Feature sleep() yield()
Pauses Thread Yes Not necessarily
Duration Specific time Indefinite / scheduler-
dependent
State TIMED_WAITING RUNNABLE
Interruptible Yes (InterruptedException) No
Use Case Delays, simulate work Debugging, thread fairness
Scheduler Control No influence Hints to scheduler

Java Thread Class Methods


Modifier Method Description
and Type
void start() It is used to start the execution of the thread.
void run() It is used to do an action for a thread.
static sleep() It sleeps a thread for the specified amount of time.
void
static currentThread() It returns a reference to the currently executing
Thread thread object.
void join() It waits for a thread to die.
int getPriority() It returns the priority of the thread.
void setPriority() It changes the priority of the thread.
String getName() It returns the name of the thread.
void setName() It changes the name of the thread.
long getId() It returns the id of the thread.
boolean isAlive() It tests if the thread is alive.

static yield() It causes the currently executing thread object to


void pause and allow other threads to execute
temporarily.
void suspend() It is used to suspend the thread. Thread.suspend()
is a method that was used to pause a thread's
execution indefinitely until it was explicitly
resumed using Thread.resume().
void resume() It is used to resume the suspended thread.
void stop() It is used to stop the thread.
void destroy() It is used to destroy the thread group and all of its
subgroups.
boolean isDaemon() It tests if the thread is a daemon thread.
void setDaemon() It marks the thread as daemon or user thread.
void interrupt() It interrupts the thread.
boolean isinterrupted() It tests whether the thread has been interrupted.

static interrupted() It tests whether the current thread has been


boolean interrupted.
static int activeCount() It returns the number of active threads in the
current thread's thread group.
void checkAccess() It determines if the currently running thread has
permission to modify the thread.
static holdLock() It returns true if and only if the current thread
boolean holds the monitor lock on the specified object.
static dumpStack() It is used to print a stack trace of the current
void thread to the standard error stream.
StackTra getStackTrace() It returns an array of stack trace elements
ceEleme representing the stack dump of the thread.
nt[]
static int enumerate() It is used to copy every active thread's thread
group and its subgroup into the specified array.
Thread.S getState() It is used to return the state of the thread.
tate
ThreadG getThreadGroup
It is used to return the thread group to which this
roup () thread belongs
String toString() It is used to return a string representation of this
thread, including the thread's name, priority, and
thread group.
void notify() It is used to give the notification for only one
thread which is waiting for a particular object.
void notifyAll() It is used to give the notification to all waiting
threads of a particular object.
void setContextClassL It sets the context ClassLoader for the Thread.
oader()
ClassLoa getContextClass It returns the context ClassLoader for the thread.
der Loader()
static getDefaultUncau It returns the default handler invoked when a
Thread.U ghtExceptionHan thread abruptly terminates due to an uncaught
ncaughtE dler() exception.
xception
Handler
static setDefaultUncau It sets the default handler invoked when a thread
void ghtExceptionHan abruptly terminates due to an uncaught exception.
dler()

5. Synchronization in Java
Why Synchronization?
When multiple threads access shared resources, inconsistent or incorrect results can
occur. This is called a race condition.
Real-World Analogy:
Two people trying to withdraw money from the same bank account at the same
time, but the bank doesn’t check the balance between withdrawals — chaos ensues

Java Example: Race Condition


class Counter {
int count = 0;

public void increment() {


count++; // Not an atomic operation!
}
}

public class RaceConditionDemo {


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

Thread t1 = new Thread(() -> {


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

Thread t2 = new Thread(() -> {


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

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

System.out.println("Final count: " + counter.count);


}
}

Expected vs Actual Output


• Expected output: 2000
• Actual output: Often less than 2000, due to race condition

Why It Happens:
• count++ is not atomic – it's a combo of:
1. Read count
2. Add 1
3. Write back to count
Multiple threads can interleave during these steps, causing lost updates.

Fixing with synchronized


class Counter {
int count = 0;

public synchronized void increment() {


count++;
}
}
or using AtomicInteger:
import java.util.concurrent.atomic.AtomicInteger;

class Counter {
AtomicInteger count = new AtomicInteger(0);

public void increment() {


count.incrementAndGet();
}
}

Synchronized Keyword:
Ensures mutual exclusion – only one thread can access the block at a time.
Synchronized Method:
class Counter {
int count = 0;

public synchronized void increment() {


count++;
}
}
Synchronized Block:
synchronized(object) {
// critical section
}
Example:
class Counter {
int count = 0;

public void increment() {


synchronized (this) {
count++;
}
}
}
Synchronization is important when multiple threads are writing to shared data.

6. Deadlock
What is Deadlock?
A deadlock occurs when two or more threads are blocked forever, each waiting on
the other to release a resource.
Deadlock Conditions:
1. Mutual Exclusion
2. Hold and Wait
3. No Preemption
4. Circular Wait
Deadlock Example:
class DeadlockExample {
static final Object Lock1 = new Object();
static final Object Lock2 = new Object();

public static void main(String[] args) {


Thread t1 = new Thread(() -> {
synchronized (Lock1) {
System.out.println("Thread 1: Holding
Lock1...");
try { Thread.sleep(100); } catch (Exception e)
{}
synchronized (Lock2) {
System.out.println("Thread 1: Acquired
Lock2");
}
}
});

Thread t2 = new Thread(() -> {


synchronized (Lock2) {
System.out.println("Thread 2: Holding
Lock2...");
try { Thread.sleep(100); } catch (Exception e)
{}
synchronized (Lock1) {
System.out.println("Thread 2: Acquired
Lock1");
}
}
});

t1.start();
t2.start();
}
}
Avoiding Deadlock:
• Always acquire locks in a consistent order
• Use timeout locks like tryLock() from java.util.concurrent.locks
• Minimize the use of nested synchronization

7. Thread Priorities
Threads can be assigned priorities using:
thread.setPriority(Thread.MIN_PRIORITY); // 1
thread.setPriority(Thread.NORM_PRIORITY); // 5 (default)
thread.setPriority(Thread.MAX_PRIORITY); // 10
Note: Thread scheduling is JVM and OS dependent.

8. Best Practices for Multithreading


• Avoid unnecessary synchronization
• Prefer Runnable over Thread
• Avoid shared mutable data
• Use ExecutorService for thread pool management
• Prefer concurrent collections (e.g., ConcurrentHashMap)
• Always join() threads when waiting for results

wait() and notify() in Java


These methods are part of inter-thread communication. They help threads
communicate and coordinate with each other, especially when they are sharing
resources.

Why Do We Need Them?


Imagine one thread is producing data and another thread is consuming it.
• If the buffer is empty, the consumer should wait.
• If the buffer is full, the producer should wait.
• When something changes (data produced/consumed), the thread should
notify the waiting thread.

Defined In
These methods are defined in the Object class, not in Thread. Why? Because
every object in Java has an intrinsic lock (monitor), and threads can synchronize
on any object.

Key Methods
Method Description
wait() Causes the current thread to wait (pause) until another thread
calls notify() or notifyAll() on the same object.
notify() Wakes up a single thread that's waiting on the object's monitor.
notifyAll() Wakes up all threads waiting on the object.
These must be called inside a synchronized block or method, else Java throws
IllegalMonitorStateException.

Basic Example: Producer-Consumer


class SharedResource {
private int data;
private boolean isProduced = false;

public synchronized void produce(int value) throws InterruptedException {


while (isProduced) {
wait(); // Wait until data is consumed
}
data = value;
System.out.println("Produced: " + data);
isProduced = true;
notify(); // Notify consumer
}

public synchronized void consume() throws InterruptedException {


while (!isProduced) {
wait(); // Wait until data is produced
}
System.out.println("Consumed: " + data);
isProduced = false;
notify(); // Notify producer
}
}
Threads:
java
CopyEdit
class Producer extends Thread {
SharedResource resource;
Producer(SharedResource res) { resource = res; }

public void run() {


int value = 1;
while (true) {
try {
resource.produce(value++);
Thread.sleep(500);
} catch (InterruptedException e) { e.printStackTrace(); }
}
}
}

class Consumer extends Thread {


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

public void run() {


while (true) {
try {
resource.consume();
Thread.sleep(500);
} catch (InterruptedException e) { e.printStackTrace(); }
}
}
}
Main Method:
public class Test {
public static void main(String[] args) {
SharedResource res = new SharedResource();
new Producer(res).start();
new Consumer(res).start();
}
}

Important Points
• Always call wait() and notify() within a synchronized context.
• wait() releases the lock and pauses.
• notify() does not release the lock immediately. It just tells one waiting
thread: "Get ready!"
• Prefer while over if when checking conditions before waiting (to avoid
spurious wakeups).

wait vs sleep
Feature wait() sleep()
Belongs to Object class Thread class
Lock released Yes No
Needs sync? Yes No
Wakeup by notify()/notifyAll() Time-based or interrupt

Use Cases
• Producer-Consumer problems
• Reader-Writer locks
• Thread-safe queues or buffers
• Resource pool management

Summary Table
Feature Thread Runnable
Extends Thread class Runnable interface
Inheritance flexibility Cannot extend another class Can extend any class
Multiple threads No (requires separate objects) Yes
Recommended For simple programs For scalable apps

Java Interfaces
What is an Interface in Java?
An interface in Java is a reference type, similar to a class, that can contain only
constants, method signatures, default methods, static methods, and nested types.
Interfaces cannot have instance fields.
Definition:
An interface is a contract that defines a set of abstract methods that the
implementing class must define.

Syntax of Interface
interface InterfaceName {
// abstract method
void method1();

// default method
default void method2() {
System.out.println("Default method in Interface");
}

// static method
static void method3() {
System.out.println("Static method in Interface");
}
}

Implementing an Interface
interface Animal {
void sound();
}

class Dog implements Animal {


public void sound() {
System.out.println("Woof!");
}
}
Output:
Woof!

Key Points
Feature Description
Keyword interface
Methods by public and abstract (unless defined as default or static)
default
Fields public static final (i.e., constants)
Multiple A class can implement multiple interfaces (resolving
inheritance multiple inheritance issue)
No Constructors Interfaces cannot be instantiated directly

Interface vs Abstract Class vs Class


Feature Class Abstract Class Interface
Instantiation Yes No No
Constructors Yes Yes No constructors
Inheritance Single Single Multiple
Methods Concrete methods Abstract + Abstract + Default +
Concrete Static
Variables Instance + static Instance + public static final only
static
Access Any (private, Any All methods are public
Modifiers protected…) by default
Use Case Complete Partial Total abstraction
implementation abstraction

Why Use Interfaces?


• To achieve 100% abstraction
• To support multiple inheritance in Java
• To decouple code (e.g., using interfaces for data access, logging, payment
gateways)
• To define contracts for polymorphism

Interface with Multiple Implementations


interface Payment {
void pay(int amount);
}

class CreditCardPayment implements Payment {


public void pay(int amount) {
System.out.println("Paid $" + amount + " via Credit Card.");
}
}

class PayPalPayment implements Payment {


public void pay(int amount) {
System.out.println("Paid $" + amount + " via PayPal.");
}
}

public class PaymentDemo {


public static void main(String[] args) {
Payment p1 = new CreditCardPayment();
Payment p2 = new PayPalPayment();

p1.pay(100);
p2.pay(200);
}
}

Java 8 and Beyond: New Interface Features


Default Methods
java
CopyEdit
interface Greeting {
default void sayHello() {
System.out.println("Hello from Interface!");
}
}
• Helps in adding new methods without breaking existing implementations.
Static Methods
interface Utility {
static void display() {
System.out.println("Static method in interface");
}
}

Multiple Interface Implementation


java
CopyEdit
interface A {
void display();
}

interface B {
void show();
}

class C implements A, B {
public void display() {
System.out.println("Display from A");
}
public void show() {
System.out.println("Show from B");
}
}

Interface Inheritance (Interface extending another Interface)


interface X {
void xMethod();
}

interface Y extends X {
void yMethod();
}

class Z implements Y {
public void xMethod() {
System.out.println("X Method");
}
public void yMethod() {
System.out.println("Y Method");
}
}

Functional Interface (Java 8+)


• Interface with only one abstract method
• Can be used with Lambda expressions
@FunctionalInterface
interface Operation {
int perform(int a, int b);
}

public class LambdaDemo {


public static void main(String[] args) {
Operation add = (a, b) -> a + b;
System.out.println(add.perform(5, 3)); // Output: 8
}
}

Marker Interfaces
• Interfaces with no methods (used to provide metadata)
interface Serializable {} // Marker Interface

Summary
Feature Interface
Full Abstraction Yes
Multiple Inheritance Yes
Default Methods Since Java 8
Static Methods Since Java 8
Functional Interface Since Java 8 (@FunctionalInterface)
Use Case Contracts, Plugins, Polymorphism
default Keyword in Java
The default keyword in Java has two main uses:

1. Default Methods in Interfaces (Java 8+)


Purpose:
To allow interfaces to have method implementations, without affecting classes
that already implement the interface.

Syntax:
interface MyInterface {
default void show() {
System.out.println("Default method in interface");
}
}
Example:
interface Animal {
default void eat() {
System.out.println("This animal eats food");
}
}

class Dog implements Animal {


// No need to override eat(), unless we want to
}

public class Main {


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

Why Use Default Methods?


• To extend interfaces with new methods without breaking existing
implementations.
• Useful in API evolution (e.g., Java collections framework).
• Acts like optional methods in interfaces.

Overriding Default Method


class Cat implements Animal {
@Override
public void eat() {
System.out.println("Cat eats fish");
}
}

Default Method vs Abstract Method


Feature Default Method Abstract Method
Has body? Yes No
Can override? Yes Must override
Introduced in Java 8 Since beginning

Conflict Scenario: Multiple Interfaces with Same Default Method


interface A {
default void greet() {
System.out.println("Hello from A");
}
}

interface B {
default void greet() {
System.out.println("Hello from B");
}
}

class C implements A, B {
public void greet() {
A.super.greet(); // or B.super.greet()
}
}
Note: You must override the method in the implementing class to resolve
ambiguity.
Java Applets: Detailed Study Notes
What is an Applet in Java?
An applet is a small Java program that is embedded in a web page and runs in
the context of a browser or an applet viewer. It is used primarily for creating
dynamic and interactive web applications.
Applets are a type of GUI (Graphical User Interface) program and are not
executed using the main() method like standard Java applications.

Key Features of Applets


• Applets run in a web browser using the Java Plugin.
• They are embedded in HTML pages.
• They do not require a main() method.
• Can be executed using the appletviewer tool or a browser that supports
Java.

Applet Class Hierarchy


java.lang.Object
↳ java.awt.Component
↳ java.awt.Container
↳ java.awt.Panel
↳ java.applet.Applet
All applets are subclasses of java.applet.Applet or javax.swing.JApplet.

Import Statements
import java.applet.Applet;
import java.awt.Graphics;

Applet Lifecycle Methods


Method Description
init() Called once when the applet is first loaded. Used for initialization.
start() Called after init() or when the applet is restarted.
stop() Called when the applet is stopped or the user navigates away.
destroy() Called when the applet is being removed from memory.
paint(Graphics g) Called to redraw the contents of the applet window.

Applet Lifecycle Diagram


Browser loads Applet

init()

start()

paint()

stop()

destroy()

Simple Applet Example


import java.applet.Applet;
import java.awt.Graphics;

/* <applet code="HelloApplet.class" width="300" height="200"></applet> */

public class HelloApplet extends Applet {


public void paint(Graphics g) {
g.drawString("Hello, World!", 50, 100);
}
}
Steps to Run:
1. Save the file as HelloApplet.java.
2. Compile:
javac HelloApplet.java
3. Create an HTML file (HelloApplet.html):
<html>
<body>
<applet code="HelloApplet.class" width="300" height="200"></applet>
</body>
</html>
4. Run using appletviewer:
appletviewer HelloApplet.html

import java.applet.Applet;
import java.awt.Graphics;

/*
<applet code="MyApplet" width="300" height="200">
</applet>
*/
public class MyApplet extends Applet {
String message = "";

// Called first — used for initialization


public void init() {
message = "Applet Initialized!";
System.out.println("Inside init()");
}

// Called after init() and each time the applet is


revisited
public void start() {
message = "Applet Started!";
System.out.println("Inside start()");
}

// Called when the applet needs to repaint its window


public void paint(Graphics g) {
g.drawString(message, 50, 100);
}
}

Common Applet Methods


Method Purpose
getCodeBase() Returns the base URL of the applet
getDocumentBase() Returns the URL of the HTML document
showStatus(String s) Displays a message in the status bar
repaint() Requests a call to the paint() method

Drawing in Applets
Using the Graphics object:
public void paint(Graphics g) {
g.drawLine(10, 10, 100, 10);
g.drawRect(20, 30, 60, 40);
g.drawOval(100, 50, 50, 50);
}

Event Handling in Applets


import java.applet.*;
import java.awt.*;
import java.awt.event.*;

public class ButtonApplet extends Applet implements ActionListener {


Button b;
public void init() {
b = new Button("Click Here");
add(b);
b.addActionListener(this);
}

public void actionPerformed(ActionEvent e) {


showStatus("Button was clicked!");
}
}

Parameters in Applet (Using <param> Tag)


import java.applet.Applet;
import java.awt.Graphics;

/* <applet code="ParamApplet.class" width="300" height="200">


<param name="message" value="Hello from PARAM!">
</applet> */

public class ParamApplet extends Applet {


String msg;
public void init() {
msg = getParameter("message");
}

public void paint(Graphics g) {


g.drawString(msg, 50, 100);
}
}

Simple Calculator Applet Example


import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;

/*
<applet code="CalculatorApplet" width="350" height="300">
</applet>
*/

public class CalculatorApplet extends Applet implements ActionListener {


TextField t1, t2, result;
Button add, sub, mul, div, clear;

public void init() {


// Set layout
setLayout(new GridLayout(6, 2, 5, 5));

// Create components
add(new Label("Number 1:"));
t1 = new TextField();
add(t1);

add(new Label("Number 2:"));


t2 = new TextField();
add(t2);

add = new Button("Add");


sub = new Button("Subtract");
mul = new Button("Multiply");
div = new Button("Divide");
clear = new Button("Clear");

result = new TextField();


result.setEditable(false);

// Add buttons
add(add);
add(sub);
add(mul);
add(div);
add(clear);

add(new Label("Result:"));
add(result);

// Register listeners
add.addActionListener(this);
sub.addActionListener(this);
mul.addActionListener(this);
div.addActionListener(this);
clear.addActionListener(this);
}

public void actionPerformed(ActionEvent e) {


try {
double n1 = Double.parseDouble(t1.getText());
double n2 = Double.parseDouble(t2.getText());
double res = 0;

if (e.getSource() == add)
res = n1 + n2;
else if (e.getSource() == sub)
res = n1 - n2;
else if (e.getSource() == mul)
res = n1 * n2;
else if (e.getSource() == div)
res = n1 / n2;
else if (e.getSource() == clear) {
t1.setText("");
t2.setText("");
result.setText("");
return;
}

result.setText(String.valueOf(res));
} catch (NumberFormatException ex) {
result.setText("Invalid input");
} catch (ArithmeticException ex) {
result.setText("Math error");
}
}
}

Applets vs Applications
Feature Applet Application
Execution Browser or appletviewer JVM (java command)
main() method Not used Required
User interaction Limited Full interaction
GUI libraries AWT AWT, Swing, JavaFX, etc.
Security Runs in sandbox (restricted) Full access to system resources

Limitations of Applets
• Requires Java plugin support in the browser (now deprecated).
• Security restrictions prevent access to local files, system commands.
• Not supported in modern browsers due to removal of NPAPI plugin.
• Replaced by Java Web Start, then by JavaFX and desktop apps.

Summary
Key Points Description
Applet is a GUI-based Java program run inside browser
Extends java.applet.Applet class
Lifecycle: init(), start(), paint(), stop(), destroy()
Run with HTML embedding or appletviewer
Deprecated in modern development
Graphics Programming in Java (AWT & GUI)
1. Introduction to Java Graphics Programming
Java enables building both console-based and GUI-based applications. GUI
applications interact with users through windows, buttons, text fields, and graphics.
Java offers the following for GUI and graphics programming:
Why Java for GUI?
• Platform-independent GUI (write once, run anywhere).
• Built-in libraries for GUI (AWT, Swing, JavaFX).
• Event-driven architecture.
• Good abstraction over native system libraries.

2. Java GUI Libraries Overview


Library Description Use Case Status
AWT Abstract Window Toolkit Basic desktop GUI, Still available but
(Java 1.0). Depends on OS- learning largely replaced
native components.
Swing Lightweight, pluggable look Richer UI Still widely used
and feel. Built on AWT. components
JavaFX Modern, styled with CSS. Modern UIs, Recommended for
Supports multimedia and dashboards, modern apps
animations. media apps

3. AWT – Abstract Window Toolkit


Key Features
• Part of java.awt package.
• Provides GUI components and containers.
• Platform-dependent.
• Basic drawing tools using Graphics class.

4. AWT Containers and Components


Containers: Hold other components (buttons, labels, etc.)
1. Window
• It's the top-most container class.
• Cannot be instantiated directly (abstract use).
• Used internally by Frame and Dialog.
Think of Window as the blank base — you don’t use it directly, but other
containers are built on top of it.

2. Panel
• A container without borders or title bar.
• Used to organize components in groups.
• You can add Panel inside a Frame or another Panel.
• Often used with layout managers.
Panel panel = new Panel();
panel.setLayout(new FlowLayout());
panel.add(new Button("Click Me"));
Think of Panel like a section on a webpage — it helps structure the layout.

3. Frame
• A top-level window.
• Has a title bar, minimize, maximize, and close buttons.
• Can host other components like Button, Panel, Label, etc.
• Most commonly used container for desktop apps.
Frame frame = new Frame("My App");
frame.setSize(300, 200);
frame.setLayout(new FlowLayout());
frame.add(new Button("Press"));
frame.setVisible(true);
Frame is like the main app window.

4. Dialog
• A pop-up window used to interact with users.
• Can be modal (blocks other windows) or non-modal.
• Often used for alerts, confirmations, or input boxes.
Dialog dialog = new Dialog(frame, "Warning", true);
dialog.setSize(200, 100);
dialog.add(new Label("Are you sure?"));
dialog.setVisible(true);
Dialog is like a pop-up alert box.

Useful Methods of Component Class


Method Description
public void add(Component c) Inserts a component on this component.
public void setSize(int width,int height) Sets the size (width and height) of the
component.
public void setLayout(LayoutManager m) Defines the layout manager for the
component.
public void setVisible(boolean status) Changes the visibility of the component, by
default false.
Components
UI elements that users interact with:
• Button, Label, TextField, TextArea, Checkbox, Choice, List.

6. Layout Managers
Manage how components are arranged inside containers.
Common Layouts
Layout Description Use Case Key Methods /
Manager Characteristics
BorderLayout Divides container Typical window add(Component,
into 5 regions: UI layout. BorderLayout.NORTH)
North, South,
East, West,
Center.
BoxLayout Aligns Toolbars, BoxLayout(container,
components vertical menus. BoxLayout.Y_AXIS)
either vertically
(Y_AXIS) or
horizontally
(X_AXIS).
CardLayout Stacks Tabbed panes, next(), previous(),
components like wizards, multi- show()
cards; only one page forms.
visible at a time.
FlowLayout Arranges Simple forms, Default for Panel.
components left dialogs.
to right, wraps to
next line.
GridBagLayout Flexible grid Complex forms Uses
layout allowing with mixed GridBagConstraints.
varying cell sizes component
and alignments. sizes.
GridLayout Creates a grid Calculator UIs, GridLayout(rows, cols)
with equal-size dashboards.
cells (rows ×
columns).
GroupLayout Aligns Often used in Supports parallel and
components in NetBeans GUI sequential groupings.
hierarchical Builder.
groups, both
horizontally and
vertically.
SpringLayout Uses constraints Fine-grained Requires manual
(springs) to define control over constraint setup.
component component
positions and positions.
spacing.

Example:
setLayout(new FlowLayout());

AWT Layout Managers


In AWT, a Layout Manager is used to arrange components (buttons, text fields,
etc.) inside a container (like Frame, Panel) in a specific pattern.

1. BorderLayout
Arranges components in five regions:
• North (top)
• South (bottom)
• East (right)
• West (left)
• Center
Analogy: Like placing items on the edges and center of a rectangular table.
setLayout(new BorderLayout());
add(new Button("North"), BorderLayout.NORTH);
add(new Button("South"), BorderLayout.SOUTH);
add(new Button("East"), BorderLayout.EAST);
add(new Button("West"), BorderLayout.WEST);
add(new Button("Center"), BorderLayout.CENTER);
Visual:
+-------- North --------+
| West | Center | East |
+-------- South --------+

2. FlowLayout
Arranges components in a row, like words in a sentence. When the row fills, it
moves to the next line.
Default layout for Panel.
Analogy: Like writing text in a paragraph — left to right.
setLayout(new FlowLayout());
add(new Button("1"));
add(new Button("2"));
add(new Button("3"));
Visual:
[1] [2] [3] [4] [5] -> wraps to next line if full

3. GridLayout
Arranges components in equal-sized rows and columns, like a spreadsheet or
table.
Analogy: Like a chessboard — every square is the same size.
setLayout(new GridLayout(2, 3)); // 2 rows, 3 columns
add(new Button("1")); // Fills row by row
Visual:
[1] [2] [3]
[4] [5] [6]

4. CardLayout
Only one component is visible at a time, like flipping cards.
Useful for tabs or wizard-style interfaces.
Analogy: Like a stack of index cards — only the top one is shown.
CardLayout cl = new CardLayout();
setLayout(cl);
add("Card1", new Button("First"));
add("Card2", new Button("Second"));
cl.show(this, "Card1");
Visual:
[ First Button ] <- click to switch to ->
[ Second Button ]
When the button named apple is clicked, we get

When the boy button is clicked, we get

5. BoxLayout (in Swing, not core AWT)


• Arranges components either vertically or horizontally.
• Often used with containers like Box, JPanel.
Analogy: Like stacking books (vertical) or placing them side by side (horizontal).

6. GridBagLayout (Advanced)
• Flexible layout like GridLayout, but allows different-sized components and
positioning.
Analogy: Like a spreadsheet where some cells span multiple rows/columns.
GridBagLayout gbl = new GridBagLayout();
setLayout(gbl);
Used in complex UIs with detailed alignment needs.

AWT Components (Nodes)


Here's a simple table of most common AWT components (nodes you add to
layouts):
Component Description Example Use
Label Displays non-editable text "Enter your name:"
Button Clickable button "Submit"
TextField Single-line text input Entering a name
TextArea Multi-line text input Entering an address
Checkbox Toggle option "I agree to terms"
CheckboxGroup Group of radio buttons "Male"/"Female"
Choice Dropdown menu Selecting a country
List Scrollable list Choosing multiple items
Canvas For custom drawings Drawing shapes
Panel Sub-container Organize components
Frame Main window Top-level app container
Dialog Pop-up window Confirmations or alerts

How to Choose a Layout?


Layout When to Use
BorderLayout App with top bar, side menu, center area
FlowLayout Simple row of buttons/fields
GridLayout Calculator-like grid, tables
CardLayout Tabbed panes, step-by-step wizards
GridBagLayout Advanced UIs with uneven sizes
BoxLayout Stack items vertically/horizontally (Swing)

7. Event-Driven Programming
GUI in Java follows an event-driven model.
Basic Event Model
1. Event Source – Button or text field
2. Event Object – e.g., ActionEvent
3. Event Listener – Handles the event (e.g., ActionListener)
Example
button.addActionListener(this);

public void actionPerformed(ActionEvent e) {


System.out.println("Button Clicked");
}

8. Panels and Canvases


Panel
• Sub-container within a frame.
• Used to group components.
Canvas
• Blank rectangular area for custom drawing.
• Use paint(Graphics g) to draw shapes.
class MyCanvas extends Canvas {
public void paint(Graphics g) {
g.drawRect(50, 50, 100, 60);
}
}

9. Drawing with Graphics Class


Methods of Graphics Class
Method Description
drawLine(x1, y1, x2, y2) Draws a line
drawRect(x, y, w, h) Rectangle outline
fillRect(...) Filled rectangle
drawOval(x, y, w, h) Oval outline
fillOval(...) Filled oval
drawString("Text", x, y) Draws text

10. AWT UI Components in Detail


Component Class Description
Label java.awt.Label Displays non-editable text
TextField java.awt.TextField Single-line text input
TextArea java.awt.TextArea Multi-line text input
Button java.awt.Button Clickable component
Checkbox java.awt.Checkbox Selectable box
CheckboxGroup java.awt.CheckboxGroup Creates radio buttons
Choice java.awt.Choice Drop-down list
List java.awt.List Scrollable list
Example: Adding a Button
Button b = new Button("Click Me");
add(b);

11. Full-Fledged Mini Project: Simple Calculator


Features
• Input two numbers.
• Perform Add, Subtract, Multiply, Divide.
• Show result on click.
Code
import java.awt.*;
import java.awt.event.*;

public class Calculator extends Frame implements ActionListener


{
TextField tf1, tf2, result;
Button add, sub, mul, div, clear;

Calculator() {
setLayout(new GridLayout(6, 2, 5, 5));

add(new Label("First Number:"));


tf1 = new TextField();
add(tf1);

add(new Label("Second Number:"));


tf2 = new TextField();
add(tf2);

add(new Label("Result:"));
result = new TextField();
result.setEditable(false);
add(result);

add = new Button("Add");


sub = new Button("Subtract");
mul = new Button("Multiply");
div = new Button("Divide");
clear = new Button("Clear");

add(add); add(sub); add(mul); add(div); add(clear);

add.addActionListener(this);
sub.addActionListener(this);
mul.addActionListener(this);
div.addActionListener(this);
clear.addActionListener(this);

setTitle("AWT Calculator");
setSize(300, 250);
setVisible(true);

addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
dispose();
}
});
}

public void actionPerformed(ActionEvent e) {


try {
double a = Double.parseDouble(tf1.getText());
double b = Double.parseDouble(tf2.getText());
double res = 0;

if (e.getSource() == add) res = a + b;


else if (e.getSource() == sub) res = a - b;
else if (e.getSource() == mul) res = a * b;
else if (e.getSource() == div) res = b != 0 ? a / b
: Double.NaN;
else if (e.getSource() == clear) {
tf1.setText(""); tf2.setText("");
result.setText("");
return;
}

result.setText(String.valueOf(res));
} catch (Exception ex) {
result.setText("Invalid input");
}
}

public static void main(String[] args) {


new Calculator();
}
}

Assignment: AWT-Based Note Saver App


A GUI app that allows the user to type a note and save it to a
file. It also has a “Load Notes” button to read and display
previously saved notes from the file.

Features:
• TextArea for typing notes
• Buttons to Save and Load notes
• Stores data in a .txt file on disk
• Uses FileWriter, BufferedReader, FileReader

Want to extend this project to support multiple files,


timestamps, or even password-protected notes?

JavaFX
What is JavaFX?
JavaFX is a modern UI toolkit for Java. It is the successor of Swing and AWT, offering:
• Rich graphical interfaces
• Declarative and hardware-accelerated UI
• FXML support (XML-based UI layout)
• CSS styling for UI components
• Integration with 2D/3D graphics, media, and web content

Features of JavaFX
Feature Description
Modern UI Build modern, desktop-like GUI
FXML Design UI separately using XML
Scene Graph Hierarchical tree of nodes
CSS Support Style UI like in web development
Multimedia Built-in support for audio and video
Charting Rich chart API: Bar, Line, Pie, etc.
3D Graphics Basic 3D support: shapes, lights, camera
Web Integration Embed web content using WebView

Architecture of JavaFX
1. Stage - Top-level container (window)
2. Scene - Holds all content inside the Stage
3. Nodes - UI elements like buttons, text fields, layouts, etc.
Stage
└── Scene
└── Parent Node (like Pane)
├── Button
├── Label
└── TextField
JavaFX Packages
Package Purpose
javafx.application Main class and lifecycle
javafx.stage Windows (Stage)
javafx.scene Scene graph
javafx.scene.control UI controls
javafx.scene.layout Layout managers
javafx.scene.text Fonts, Text
javafx.scene.paint Colors, Gradients
javafx.event Event handling
javafx.fxml FXML support

JavaFX Setup
1. Install JDK 11+ and JavaFX SDK
2. Add JavaFX SDK lib folder to your project libraries
3. Use an IDE like IntelliJ or Eclipse with JavaFX plugin

JavaFX Basic Program


import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.stage.Stage;

public class HelloFX extends Application {


public void start(Stage primaryStage) {
Label label = new Label("Hello JavaFX!");
Scene scene = new Scene(label, 300, 200);
primaryStage.setScene(scene);
primaryStage.setTitle("My First JavaFX App");
primaryStage.show();
}

public static void main(String[] args) {


launch(args);
}
}

JavaFX Layouts
Layout Description
Pane Basic container
HBox Horizontal alignment
VBox Vertical alignment
BorderPane Top, Bottom, Center, Left, Right
GridPane Table-like rows and columns
StackPane Stack components on top of each other
AnchorPane Anchor edges to parent

JavaFX UI Controls
Control Purpose
Button Clickable button
Label Display text
TextField Single-line input
TextArea Multi-line input
CheckBox Toggle on/off
RadioButton Select one from group
ComboBox Dropdown list
ListView Scrollable list
TableView Tabular data
DatePicker Date selector
Slider Value selector via slider

Styling with CSS


JavaFX uses a CSS-like syntax.
Example: style.css
.button {
-fx-background-color: #3498db;
-fx-text-fill: white;
-fx-font-size: 14px;
}
Apply CSS in Java:
scene.getStylesheets().add("style.css");

FXML - Declarative UI (Optional)


• FXML allows UI layout via XML.
• Keeps logic (Controller) separate from view (FXML).
Sample FXML:
<?xml version="1.0" encoding="UTF-8"?>
<VBox xmlns:fx="http://javafx.com/fxml" fx:controller="MyController">
<Label text="Enter Name:"/>
<TextField fx:id="nameField"/>
<Button text="Submit" onAction="#handleSubmit"/>
</VBox>
Controller Class:
java
CopyEdit
public class MyController {
@FXML private TextField nameField;

public void handleSubmit(ActionEvent e) {


System.out.println("Name: " + nameField.getText());
}
}

JavaFX Media Support


Media media = new Media("file:///your/audio.mp3");
MediaPlayer player = new MediaPlayer(media);
MediaView view = new MediaView(player);
player.play();

JavaFX Charts
Chart Type Class
Bar Chart BarChart
Line Chart LineChart
Pie Chart PieChart
Area Chart AreaChart

JavaFX Events
Button btn = new Button("Click Me");
btn.setOnAction(e -> System.out.println("Clicked!"));
You can handle key, mouse, drag, and other events.

Sample Mini Project: JavaFX Login Form


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

public class LoginApp extends Application {


@Override
public void start(Stage stage) {
Label userLabel = new Label("Username:");
TextField userField = new TextField();

Label passLabel = new Label("Password:");


PasswordField passField = new PasswordField();

Button loginBtn = new Button("Login");


Label message = new Label();

loginBtn.setOnAction(e -> {
if (userField.getText().equals("admin") &&
passField.getText().equals("123")) {
message.setText("Login Successful");
} else {
message.setText("Invalid Credentials");
}
});

GridPane grid = new GridPane();


grid.setVgap(10); grid.setHgap(10);
grid.add(userLabel, 0, 0); grid.add(userField, 1, 0);
grid.add(passLabel, 0, 1); grid.add(passField, 1, 1);
grid.add(loginBtn, 1, 2); grid.add(message, 1, 3);

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


stage.setTitle("JavaFX Login Form");
stage.setScene(scene);
stage.show();
}

public static void main(String[] args) {


launch(args);
}
}

External Tools You Might Use


• SceneBuilder: Drag-and-drop UI builder for FXML
• IntelliJ/NetBeans: With JavaFX support
• JavaFXPorts / Gluon: For mobile apps using JavaFX

Summary Table
Feature AWT Swing JavaFX
UI Design Programmatic Programmatic Declarative (FXML) or programmatic
Styling Manual Look and Feel CSS
Layouts Rigid Improved Flexible with animations
Media Support No Limited Full audio/video
3D Graphics No No Yes
Mobile Support No No Via Gluon

You might also like