Java Programming Notes-3
Java Programming Notes-3
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:
• 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).
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.
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.
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++
Java revolutionized web development with features suited for the Internet:
• Applets: Small Java programs embedded in web pages (now deprecated due to security
issues).
• 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.
HotJava was the first web browser written entirely in Java. It demonstrated Java’s capabilities,
especially running applets.
Key Points:
6. Java Environment
The Java environment consists of several components required for developing and running Java
applications.
The JDK is a software development environment for building Java applications. It includes:
• 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.
JDK Components:
The JRE is part of the JDK, necessary for running Java programs. It includes:
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.
o Compilation: The JIT compiles these hot spots into native machine code.
4. Execution: Native code runs directly on the hardware for faster performance.
• Example: HelloWorld.java
System.out.println("Hello, World!");
• What is Bytecode?
A set of intermediate instructions that can run on any device with a JVM.
• Purpose: Ensures bytecode is safe, secure, and doesn’t violate Java rules.
• Checks for:
o Stack overflows
o Security violations
6. Execution Engine
• Interpreter:
o Detects frequently used code (hotspots) and converts them to native machine code.
• 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:
Java SE (Standard Edition) provides the core functionality for developing general-purpose desktop,
server, and embedded device applications.
Key Features:
• 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
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:
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:
Use Cases:
• Smart cards
• Set-top boxes
• IoT devices
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:
Use Cases:
• 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:
Use Cases:
• SIM cards
• Secure ID cards
• 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.
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 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:
• 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:
• 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 Amazon Corretto
• Members: Oracle, IBM, Red Hat, SAP, Google, Microsoft, and other industry leaders.
• Role: After Oracle donated Java EE, it was renamed Jakarta EE and is now maintained by the
Eclipse Foundation.
• Red Hat: Maintains OpenJDK distributions, especially for enterprise Linux systems.
• 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:
• Java’s development is open and collaborative through the OpenJDK and JCP.
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.
Key Features:
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:
In modern Java web development, Servlets and JSPs are often used together in the Model-View-
Controller (MVC) architecture:
• Controller: Servlets handle client requests, process data, and forward results
Example Workflow:
Final Verdict:
Key Components:
6. Comments: Single-line (//) or multi-line (/* ... */) notes ignored by the compiler.
• mypackage: The name of the package. You can choose any valid name.
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.
Note: In this program, Scanner isn’t used, but in real-world programs, it's helpful for user input.
3. Class Declaration
• 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.
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.
• main: The name of the method. This is predefined in Java; changing it will cause errors.
• (String[] args):
5. Variable Declaration
• 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.
6. Output Statement
System.out.println(message);
• 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!".
7. Closing Braces
• } (Closing Curly Brace): Closes the main method and then the class HelloWorld.
Final Output:
Hello, World!
2. Java Tokens
Types of Tokens:
6. Comments:
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.
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.
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.
1. Allowed Characters:
o Letters (A–Z, a–z), digits (0–9), underscore (_), and dollar sign ($).
3. No Reserved Keywords:
4. Case-Sensitive:
5. No Spaces:
Valid Identifiers:
Invalid Identifiers:
• void (keyword)
• my Variable (contains space)
3. Literals (Constants)
• Literals are fixed values that do not change during program execution.
Types of Literals:
4. Operators
• Operators are special symbols that perform operations on variables and values.
Types of Operators:
• Arithmetic Operators: +, -, *, /, %
• Ternary Operator: ?:
5. Separators (Punctuators)
Common Separators:
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:
2. Multi-line Comment:
/* This is a
multi-line comment */
/**
*/
Summary:
3. Constants
Constants are fixed values that do not change during program execution.
Declaring Constants:
Types of Constants:
4. Variables
Declaring Variables:
int age = 25;
Variable Types:
5. Expressions
Examples:
• Arithmetic Expressions: a + b, x * y
a. if Statement:
System.out.println("Adult");
b. if-else Statement:
System.out.println("Pass");
} else {
System.out.println("Fail");
}
c. else if Ladder:
System.out.println("Grade A");
System.out.println("Grade B");
} else {
System.out.println("Grade C");
d. switch Statement:
int day = 3;
switch (day) {
a. for Loop:
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++;
System.out.println(num);
Types of Statements:
1. Expression Statements:
2. Declaration Statements:
o Declare variables.
o Example: int a, b, c;
o Example:
if (x > 0) {
return x;
4. Block Statements:
o Example:
int a = 5;
int b = 10;
System.out.println(a + b);
Key Takeaways:
• Control flow (if-else, switch) and loops (for, while, do-while) manage program logic.
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.
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.
Another way to take input is using BufferedReader, which is faster but requires handling exceptions.
Write a program that takes an integer N as input and prints numbers from 1 to N using a loop.
Example:
Example:
3. Calculate the Sum of First N Natural Numbers
Example:
4. Reverse a Number
Example:
5. Find Factorial of a Number
Example:
6. Check if a Number is Prime
Example:
Example:
8️. Fibonacci Series up to N Terms
Example (n = 7):
9. Print a Star Pattern
Example (n = 4):
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:
• if-else conditions
int n;
for(n=10; n>0; n--)
System.out.println("tick " + n);
int a, b;
for (a=1, b=4; a<b; a++, b--) {
System.out.println("a = " + a);
System.out.println("b = " + b);
}
int i;
boolean done = false;
i = 0;
for( ; !done; ) {
System.out.println("i is " + i);
if(i == 10) done = true;
i++;
}
for( ; ; ) {
// ...
}
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
}
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.
• 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
• Variable name
// OR
dataType arrayName[];
Examples
4. Instantiating an Array
Arrays must be initialized with a specific size using the new keyword.
Example
5. Initializing an Array
When an array is created, all elements are automatically initialized to their default values:
Example:
Example:
If you initialize only some elements, the rest will take the default values.
Example:
• Array elements are accessed using their index (starting from 0).
Example
System.out.println(numbers[0]); // Outputs 10
System.out.println(numbers[2]); // Outputs 30
System.out.println(numbers[i]);
System.out.println(num);
Example:
int[][] matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
int[][] jaggedArray = {
{1, 2, 3},
{4, 5},
{6, 7, 8, 9}
};
9. Array Length
System.out.println(numbers.length); // Outputs 3
Using System.arraycopy():
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.
Here is a list of the most frequently used methods of the Arrays class:
Method Description
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.stream(array) Converts an array into a stream (useful for Java Stream API).
import java.util.Arrays;
Output:
import java.util.Arrays;
Output:
Index of 5: 3
import java.util.Arrays;
Output:
import java.util.Arrays;
Output:
max = arr[i];
System.out.println();
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.
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.
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.
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.
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:
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>();
// Printing elements
System.out.println(al);
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>();
// Printing elements
System.out.println(ll);
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>();
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();
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:
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.
// Printing the top element and removing it from the PriorityQueue container
System.out.println(pQueue.poll());
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:
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.
// clear() method
de_que.clear();
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:
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.
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
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:
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.
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
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:
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.
hm.put(1, "Geeks");
hm.put(2, "For");
hm.put(3, "Geeks");
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).
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.
HashMap Map Key-value pair with fast lookups; allows one null key.
size() Returns the number of elements in the set. int size = set.size();
Map
Adds a key-value pair
(HashMap, put(K key, V value) map.put(1, "Apple");
to the map.
TreeMap)
Returns a collection
Collection<String> values =
values() of all values in the
map.values();
map.
Depends on Depends on
Performance Depends on implementation
implementation implementation
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).
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:
Java provides the ArrayList class, which acts as a dynamic array. It can grow or shrink in size as
needed.
Method Description
import java.util.ArrayList;
// Add elements
numbers.add(10);
numbers.add(20);
numbers.add(30);
// Print elements
numbers.add(1, 15);
numbers.remove(2);
// Update an element
numbers.set(0, 5);
// Get size
Output:
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.
• Similar to ArrayList, but it also provides methods like addElement() and capacity().
import java.util.Vector;
// Add elements
fruits.add("Apple");
fruits.add("Banana");
fruits.add("Cherry");
// Print elements
fruits.add(1, "Orange");
// Remove an element
fruits.remove("Banana");
// Check capacity
If you want to implement your own dynamic array, you can do so by resizing the array manually using
System.arraycopy().
// Constructor
public DynamicArray() {
capacity = 2;
size = 0;
// Add an element
if (size == capacity) {
resize();
arr[size] = element;
size++;
capacity = capacity * 2;
arr = newArr;
// Get an element
return arr[index];
// Get size
public int size() {
return size;
System.out.println();
dynamicArray.add(1);
dynamicArray.add(2);
dynamicArray.add(4);
dynamicArray.print(); // Output: 1 2 3 4
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.
• 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.
• This creates a new string object in the heap memory, even if the string already exists in the
String Pool.
The String class provides many useful methods for string manipulation.
Method Description
concat(string) Concatenates the specified string to the end of the current string.
Output:
Character at index 1: e
Index of 'Java': 7
if (str.equals(reversed)) {
} else {
Output:
madam is a palindrome.
System.out.println("Programming Languages:");
System.out.println(lang);
}
Output:
Programming Languages:
Java
Python
C++
JavaScript
int count = 0;
if (str.charAt(i) == target) {
count++;
Output:
Output:
Method Description
replace(start, end, string) Replaces characters in the specified range with a new string.
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.
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:
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
John 85
Alice 92
Bob 78
Example Output
Alice - 92
John - 85
Bob - 78
Alice - 92
John - 85
Bob - 78
Problem Statement
Write a Java program that reads a text file, processes its content, and performs the following
operations:
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 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
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)
void display() {
System.out.println("Brand: " + brand + ", Year: " +
year);
}
}
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);
}
}
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.
// 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;
}
void display() {
System.out.println("Brand: " + brand + ", Year: " +
year);
}
}
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.
// Parameterized Constructor
Car(String b, int y) {
brand = b;
year = y;
}
void display() {
System.out.println("Brand: " + brand + ", Year: " +
year);
}
}
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");
}
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
Counter() {
count++; // Incrementing static variable
}
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
}
// Child Class
class Dog extends Animal {
void bark() {
System.out.println("Dog barks.");
}
}
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.");
}
}
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.");
}
}
interface Swimable {
void swim();
}
// Child class
class Dog extends Animal {
void display() {
super.display(); // Calls the parent class method
System.out.println("This is a Dog.");
}
}
void eat() {
System.out.println("Animal eats.");
}
}
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.
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
}
Output:
Using resource...
Resource closed properly
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;
}
#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;
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);
}
}
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;
}
class MathOperations {
public:
int add(int a, int b) {
return a + b;
}
4. Static Members
Java
• Declared using static.
Java Example:
class Counter {
static int count = 0; // Shared among all objects
Counter() {
count++;
}
class Counter {
public:
static int count; // Declaration
Counter() {
count++;
}
// Definition
int Counter::count = 0;
Differences:
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 Animal {
public:
void eat() { cout << "Eating..." << endl; }
};
6. Abstract Classes
Java
• Uses abstract keyword.
Java Example:
abstract class Animal {
abstract void makeSound();
}
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
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
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
}
}
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.
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
}
➤ 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.");
}
}
}
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.");
}
➤ 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);
}
}
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.
Answer: a)
Explanation: The finally block is always executed after the try block, regardless of
whether an exception was thrown.
Answer: b)
Explanation: NullPointerException is an unchecked exception, meaning it does not
need to be declared or caught.
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.
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.
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
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
t1.start();
t2.start();
t1.join();
t2.join();
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.
class Counter {
AtomicInteger count = new AtomicInteger(0);
Synchronized Keyword:
Ensures mutual exclusion – only one thread can access the block at a time.
Synchronized Method:
class Counter {
int count = 0;
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();
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.
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.
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();
}
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
p1.pay(100);
p2.pay(200);
}
}
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 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");
}
}
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:
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");
}
}
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.
Import Statements
import java.applet.Applet;
import java.awt.Graphics;
import java.applet.Applet;
import java.awt.Graphics;
/*
<applet code="MyApplet" width="300" height="200">
</applet>
*/
public class MyApplet extends Applet {
String message = "";
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);
}
/*
<applet code="CalculatorApplet" width="350" height="300">
</applet>
*/
// Create components
add(new Label("Number 1:"));
t1 = new TextField();
add(t1);
// 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);
}
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. 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.
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());
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
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.
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);
Calculator() {
setLayout(new GridLayout(6, 2, 5, 5));
add(new Label("Result:"));
result = new TextField();
result.setEditable(false);
add(result);
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();
}
});
}
result.setText(String.valueOf(res));
} catch (Exception ex) {
result.setText("Invalid input");
}
}
Features:
• TextArea for typing notes
• Buttons to Save and Load notes
• Stores data in a .txt file on disk
• Uses FileWriter, BufferedReader, FileReader
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 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
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.
loginBtn.setOnAction(e -> {
if (userField.getText().equals("admin") &&
passField.getText().equals("123")) {
message.setText("Login Successful");
} else {
message.setText("Invalid Credentials");
}
});
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