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

Java Basic

The document provides an overview of objects in Java, explaining the concept of classes as blueprints for creating objects, their state and behavior, and various methods for object creation. It also covers packages for organizing code, access modifiers for controlling visibility, and methods including predefined and user-defined types, along with constructors and their overloading. Additionally, it highlights the immutability of strings in Java and their significance in programming.

Uploaded by

Sneha Mahamuni
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

Java Basic

The document provides an overview of objects in Java, explaining the concept of classes as blueprints for creating objects, their state and behavior, and various methods for object creation. It also covers packages for organizing code, access modifiers for controlling visibility, and methods including predefined and user-defined types, along with constructors and their overloading. Additionally, it highlights the immutability of strings in Java and their significance in programming.

Uploaded by

Sneha Mahamuni
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 73

Objects in Java

 A class is like a blueprint or template used to create objects.


 It defines the structure and behaviour of its objects (or instances).
 When we create an object using a class, we call it an instance of that class.
 State: Stored in variables, with each variable having a unique name to identify the
object.
 Behaviour: Defined by functions or methods associated with the object.
Example
class Rectangle {
double length;
double breadth;
}
 A class defines a new type of data. In this case, the new data type is Rectangle.
 Declaring a class only creates a template; it does not create any physical entity (i.e.,
no memory is allocated).
Objects of type Rectangle are created as follows, and these objects occupy memory:

Rectangle rec = new Rectangle(); // creates a Rectangle object called rec


 This statement creates an object rec of the class Rectangle, giving it physical
existence in memory.
 All objects of the same class share similarities by having the same behaviour.
Creating an Object

There are different ways to create an object in Java. Let us explore them one by one:
1. By new Keyword
This is the most common method to create an object of a class.
ClassName objectName = new ClassName();

2. By newInstance() Method
We can use the newInstance() method in Java to create an object of a class. This is a
reflective way to create an object:
ClassName objectName = ClassName.class.newInstance();

3. By clone() Method
The clone() method is used to create a copy of an existing object:
ClassName objectName = existingObject.clone();

4. By Deserialization
Objects can also be created from a serialized file using deserialization:
ObjectInputStream in = new ObjectInputStream(new FileInputStream("object.ser"));
ClassName objectName = (ClassName) in.readObject();
this Keyword

The this keyword in Java refers to the current object. It is used to:
1. Access instance variables when they are shadowed by method parameters.
this.variable = parameter;
2. Call other methods or constructors in the same class.
this.methodName();
this(); // Calls another constructor
3. Pass the current object as an argument.
otherMethod(this);
In short, this connects the current object with its variables, methods, or constructors.
Packages

 In Java, packages are a way to group related classes, interfaces, and sub-packages.
 They serve as a mechanism for organizing code into meaningful modules, which
makes it easier to maintain, access, and reuse.
Why Use Packages?
1. Organized Structure: Helps avoid clutter by grouping related classes.
2. Namespace Management: Prevents naming conflicts by encapsulating classes in
different packages.
3. Access Control: Allows controlling access levels of classes and methods, providing
encapsulation.
4. Reusability: Encourages reuse of existing classes or frameworks by importing them
as packages.
5. Scalability: Makes it easier to scale large applications by separating components into
packages.
Built-in Packages

 These are pre-defined packages provided by Java.


 They contain commonly used classes and interfaces that help developers perform
various standard tasks like input/output, data structures, networking, and database
management.
Examples of Built-in Packages:
1. java.lang:
o Contains fundamental classes like String, Math, Object, Thread, etc.

o Automatically imported in every Java program.

2. java.util:
o Provides utility classes like ArrayList, HashMap, Collections, Date, etc.

o Often used for working with collections and data manipulation.

3. java.io:
o Contains classes for input and output operations like File, BufferedReader,
FileWriter, etc.
4. java.net:
o Supports networking tasks such as creating sockets and handling URLs.
Examples include Socket, URL, and HttpURLConnection.
5. java.sql:
o Used for database connectivity and management. Examples include
Connection, Statement, and ResultSet.
6. javax.swing:
o Provides classes for creating graphical user interfaces (GUIs), such as JButton,
JFrame, and JPanel.
User-defined Packages

 User-defined Packages are custom packages created by developers to organize their


own classes and interfaces logically.
 They are designed to modularize code for better maintainability and reuse.
Steps to Create and Use a User-defined Package:
1. Create a Package:
Define the package name using the package keyword at the top of your Java file. Save the file
in a directory matching the package name.
Example:
package mypackage;
public class MyClass {
public void greet() {
System.out.println("Hello from MyClass!");
}
}
2. Compile the Package:
Use the javac command with the -d option to specify the directory structure for the package.
javac -d . MyClass.java
3. Use the Package in Another Class:
Import the package using the import keyword.
import mypackage.MyClass;
public class Main {
public static void main(String[] args) {
MyClass obj = new MyClass();
obj.greet();
}
}
Access Modifiers

 Access modifiers define the visibility and scope of classes, methods, variables, and
constructors.
 They control which parts of the program can access certain components.
 Java provides four types of access modifiers: public, protected, default (no keyword),
and private.
 They help in encapsulation, data hiding, and security within a program.
Types of Access Modifiers

1. Public
 Scope: Accessible from anywhere in the program, including outside the package.
 Use Case: Used for classes, methods, or variables that need to be universally
accessible.
Example:
public class PublicClass {
// Public method: can be accessed from anywhere in the program.
public void display() {
// Prints a message indicating this is a public method.
System.out.println("This method is public.");
}
}
2. Private
 Scope: Accessible only within the same class where it is defined.
 Use Case: Used to implement encapsulation by hiding sensitive data or internal
implementation details from other classes.
Example:
public class PrivateExample {
// Private variable: cannot be accessed directly outside this class.
private String secret = "Hidden";

// Private method: accessible only within this class.


private void displaySecret() {
// Prints the value of the private variable.
System.out.println(secret);
}
}
3. Protected
 Scope: Accessible within the same package and by subclasses (even if they are in
different packages).
 Use Case: Commonly used in inheritance to allow child classes to access parent class
members while keeping them hidden from other classes.
Example:
package mypackage;
public class ProtectedExample {
// Protected method: can be accessed within the same package
// or by subclasses in other packages.
protected void show() {
// Prints a message indicating this is a protected method.
System.out.println("This is a protected method.");
}
}
4. Default (Package-Private) (No keyword)
 Scope: Accessible only within the same package (not visible outside the package).
 Use Case: Useful for restricting access within a package to group-related classes
together.
Example:
class DefaultExample {
// Default access method: accessible only within the same package.
void display() {
// Prints a message indicating this is a default access method.
System.out.println("This is default access.");
}
}
6. Comparison
The table below summarizes the available access modifiers. We can see that a class,
regardless of the access modifiers used, always has access to its members:

Modifie Subclas
Class Package World
r s

public Y Y Y Y

protected Y Y Y N

default Y Y N N

private Y N N N

The canonical order applies to the field, methods, classes, and modules. Here’s a customary
recommendation for field modifiers:
 Annotation
 public/protected/private
 static
 final
 transient
 volatile
Function in Java

 A function is a collection of statements or a block of code that performs a specific


task.
 It allows code reuse without retyping.
 A function is executed only when it is called.
 In Java, a function is also referred to as a method.
Method Declaration in Java:
 Method name
 Return type
 Visibility modifier
 Parameters
 Method body
// Method declaration
public int max(int x, int y) {
// public: the public is a modifier, meaning the method is accessible from outside its class.

// Method body
}

Method Calling in Java:


 A method must be called to perform a task.
 When a method is called, program control transfers to the called method.
public class Example {
// Function to return a maximum of two numbers
public static int max(int x, int y) {
if(x > y)
return x;
else
return y;
}
// Driver Method
public static void main(String arg[]) {
int a = 10;
int b = 20;
// Method Calling
int maximum = max(a, b);
System.out.println(maximum);
}
}
Output:
20
Types of Methods in Java

In Java, there are two types of methods:


1. Predefined Method
2. User-defined Method

Predefined Method
 Definition: Methods that are already defined in Java's class libraries (also called built-
in or standard library methods).
 Usage: You can use these methods directly in your program without defining them
yourself.
 Examples:
o Math class: sqrt(), max(), min(), round(), etc.

o String class: length(), toUpperCase(), toLowerCase(), equals(), etc.

Example: Find the maximum of two numbers using the built-in method.

public class MaxOfTwoNumbers {


public static void main(String args[]) {
// Maximum of two numbers using Math.max()
int maximum = Math.max(100, 30);
System.out.println(maximum);
}
}
Output:
100
User-defined Method

 The method written by the user or programmer is called the user-defined method.
 We can modify these methods based on our requirements.
 Let’s discuss the user-defined method with all four combinations of arguments and
return type-
1. No Arguments and No Return Value
 Definition: The method does not receive any data and does not return anything.
 Syntax:
 void function() {
 // Statements
}
2. No Arguments but Returns a Value
 Definition: The method does not receive any data but returns a value to the calling
method.
 Syntax:
 int function() {
 // Statements
 return x;
}
3. Arguments Passed but No Return Value
 Definition: The method receives arguments but does not return anything.
 Syntax:
 int function(int x) {
 // Statements
}
4. Arguments Passed and Returns a Value
 Definition: The method accepts arguments and returns a value to the calling method.
 Syntax:
 int function(int x) {
 // Statements
 return x;
}
Method overloading

 Method overloading in Java is a feature that allows a class to have multiple methods
with the same name but different parameter lists
 It enables polymorphism and improves code readability by allowing similar actions
with different inputs to be grouped under one method name.
 All overloaded methods share the same name.
 They must differ in one or more of the following:
o Number of parameters

o Type of parameters

o Order of parameters (if types are different)

Example with Comments

class Calculator {
// Overloaded method: adds two integers
int add(int a, int b) {
return a + b;
}

// Overloaded method: adds two doubles


double add(double a, double b) {
return a + b;
}

// Overloaded method: adds three integers


int add(int a, int b, int c) {
return a + b + c;
}
}

public class Main {


public static void main(String[] args) {
// Creating an object of Calculator class
Calculator calc = new Calculator();

// Calls the method that adds two integers


System.out.println(calc.add(2, 3)); // Output: 5

// Calls the method that adds two doubles


System.out.println(calc.add(2.5, 3.5)); // Output: 6.0

// Calls the method that adds three integers


System.out.println(calc.add(1, 2, 3)); // Output: 6
}
}
Constructor in Java

 A Constructor is a unique method used to initialize the newly created object. It has
the same name as the class.
 We can create a constructor with multiple parameters or no parameters.
 A class can have multiple constructors, and it totally depends on the programmer to
make objects in different ways, which will invoke the corresponding constructor.
 We generally use constructors to initialize an object's instance variables to a custom
value or a default value.
1. Default Constructor
 A default constructor is a constructor without any parameters.
 If no constructor is defined in a class, the Java compiler automatically provides a
default constructor.
 It initializes the object with default values (e.g., 0 for numbers, null for objects).
Example:

class Example {
int number;
String text;

// Default Constructor
Example() {
number = 0;
text = "Default";
}

void display() {
System.out.println("Number: " + number + ", Text: " + text);
}
}

public class Main {


public static void main(String[] args) {
Example obj = new Example();
obj.display();
}
}
2. Parameterized Constructor
 A parameterized constructor allows you to initialize an object with specific values.
 It takes arguments that can be used to set instance variables.
Example:

class Example {
int number;
String text;

// Parameterized Constructor
Example(int num, String str) {
number = num;
text = str;
}

void display() {
System.out.println("Number: " + number + ", Text: " + text);
}
}

public class Main {


public static void main(String[] args) {
Example obj = new Example(42, "Hello");
obj.display();
}
}

3. Copy Constructor
 A copy constructor initializes an object by copying the fields of another object of the
same class.
 Java does not provide a default copy constructor, but you can define one explicitly.
Example:

class Example {
int number;
String text;

// Parameterized Constructor
Example(int num, String str) {
number = num;
text = str;
}

// Copy Constructor
Example(Example obj) {
number = obj.number;
text = obj.text;
}

void display() {
System.out.println("Number: " + number + ", Text: " + text);
}
}

public class Main {


public static void main(String[] args) {
Example obj1 = new Example(42, "Original");
Example obj2 = new Example(obj1); // Using Copy Constructor
obj2.display();
}
}
Constructor Overloading

 Like method overloading, constructors can have multiple forms with different
parameters.
 Example:
 class Car {
 String model;
 Car() { model = "Default"; } // Default constructor
 Car(String model) { this.model = model; } // Parameterized constructor
 }
Constructor Signature
 Defined by its parameter list.
 Does not include the return type because constructors do not have one.
Key Differences Between Methods and Constructors:

String in Java

 A String in Java is a sequence of characters, but unlike other mutable data structures,
a String is immutable.
 Once a String object is created, its value cannot be changed.
 For instance, if you perform an operation such as concatenation or substring, it
doesn’t modify the original string but instead creates a new String object.
Here’s an example:
String str = "Hello";
str = str + " World"; // A new object is created, and the original "Hello" remains unchanged.
The immutability of strings provides advantages like thread safety and ease of caching,
especially when strings are used as keys in collections like HashMap.
String Pooling
 Java optimizes memory by storing string literals in a special area called the string
pool.
 If you create a string using a literal, Java checks the pool to see if a string with the
same value already exists. If it does, it reuses the existing reference instead of creating
a new object. For example:
String s1 = "Java";
String s2 = "Java";
System.out.println(s1 == s2); // Outputs: true
However, if you create strings using the new keyword, they are stored outside the pool:
String s3 = new String("Java");
System.out.println(s1 == s3); // Outputs: false
StringBuilder and StringBuffer

 While String is ideal for immutable operations, it is inefficient for tasks involving
frequent modifications like concatenations in loops.
 Java provides StringBuilder and StringBuffer for such scenarios, offering mutable and
efficient string manipulation.
StringBuilder
 StringBuilder is a mutable sequence of characters that allows modifications without
creating new objects.
 Not synchronized, making it faster but unsuitable for multi-threaded environments.
Example:
StringBuilder sb = new StringBuilder("Hello");
sb.append(" World"); // Modifies the original object
System.out.println(sb); // Outputs: Hello World
This approach is much more efficient than repeatedly concatenating strings using the +
operator.
StringBuffer
 Similar to StringBuilder but with synchronization, making it thread-safe for multi-
threaded environments.
 Synchronization adds a performance cost compared to StringBuilder.
Example:
StringBuffer sb = new StringBuffer("Hello");
sb.append(" World"); // Thread-safe modification
System.out.println(sb); // Outputs: Hello World
Key Differences Between String, StringBuilder, and StringBuffer

 String is immutable and suited for scenarios where the value doesn’t change or needs
to be shared across threads.
 StringBuilder is mutable, fast, and ideal for single-threaded applications.
 StringBuffer is also mutable but synchronized, making it suitable for multi-threaded
use cases.
When to Use What
 Use String when immutability is required, such as when storing keys in a HashMap
or when thread safety is critical without manual synchronization.
 Use StringBuilder when working in a single-threaded context where performance is
a priority.
 Use StringBuffer for multi-threaded applications where string modification is
frequent and thread safety is essential.
Understanding these concepts allows you to choose the right tool for the job, balancing
performance, and functionality effectively. If you'd like, I can provide specific code examples
or explore common interview questions around this topic.
Inheritance in Java

Inheritance is a key feature of object-oriented programming in Java, enabling:


 A class (subclass/child class) to inherit fields and methods from another class
(superclass/parent class).
 Code reuse and establishment of a hierarchical relationship between classes.
Key Concepts
1. Superclass and Subclass
 Superclass (Parent Class):
The class whose properties and methods are inherited by another class.
 Subclass (Child Class):
The class that inherits from the superclass.
o It can extend the functionality of the superclass by:

 Adding new methods and properties.


 Modifying existing ones.
Example:
// Superclass (Parent Class)
class Animal {
// Method in the superclass
void eat() {
System.out.println("This animal eats food.");
}
}
// Subclass (Child Class) inheriting from Animal
class Dog extends Animal {
// Subclass-specific method
void bark() {
System.out.println("The dog barks.");
}
}

// Main class to test inheritance


public class Main {
public static void main(String[] args) {
// Create an instance of the subclass Dog
Dog dog = new Dog();
// Call the inherited method from the superclass
dog.eat(); // Output: This animal eats food.

// Call the subclass-specific method


dog.bark(); // Output: The dog barks.
}
}
2. The super Keyword
The super keyword is used to:
 Call a superclass constructor.
 Access a superclass method or field that is overridden or hidden in the subclass.

Usage in Constructor:
class Superclass {
// Constructor for Superclass
Superclass(String name) {
System.out.println("Superclass constructor called for: " + name);
}
}

class Subclass extends Superclass {


// Constructor for Subclass
Subclass(String name) {
super(name); // Calls Superclass constructor
System.out.println("Subclass constructor called for: " + name);
}
}
Accessing Methods/Fields:
class Animal {
// Method in the superclass
void sound() {
System.out.println("Animals make sound.");
}
}
class Dog extends Animal {
// Overriding the superclass method
void sound() {
super.sound(); // Calls the superclass method 'sound'
System.out.println("Dogs bark."); // Additional behavior specific to Dog
}
}
3. Method Overriding
 Method overriding occurs when a subclass provides its own implementation of a
method already defined in its superclass.
 This enables dynamic (runtime) polymorphism.

Rules for Overriding:


 The method in the subclass must have the same name, return type, and parameters as
the superclass method.
 The access modifier of the overriding method cannot be more restrictive than that of
the overridden method.
 The overriding method can throw only those exceptions that are allowed by the
overridden method.

Example:
class Animal {
void sound() {
System.out.println("Animals make sound.");
}
}

class Dog extends Animal {


@Override
void sound() { // Method overriding
System.out.println("Dogs bark.");
}
}

public class Main {


public static void main(String[] args) {
Animal myDog = new Dog(); // Polymorphism
myDog.sound(); // Calls the overridden method in Dog
}
}
Polymorphism in Java

Polymorphism allows objects to take on multiple forms, enabling a single interface to


represent different types or behaviours.
In Java, polymorphism is mainly categorized into:
1. Compile-time Polymorphism (Overloading)
2. Runtime Polymorphism (Overriding)
Example: You have: A superclass Animal, Subclasses Cat and Dog with polymorphism, you
can create a method that accepts an Animal object as its parameter but pass in
a Cat or Dog object.

class Animal {
void sound() {
System.out.println("Animal makes a sound");
}
}
class Cat extends Animal {
void sound() {
System.out.println("Cat meows");
}
}
class Dog extends Animal {
void sound() {
System.out.println("Dog barks");
}
}
public class PolymorphismDemo {
public static void main(String[] args) {
Animal myAnimal1 = new Cat();
Animal myAnimal2 = new Dog();
myAnimal1.sound(); // Outputs: Cat meows
myAnimal2.sound(); // Outputs: Dog barks
}
}

Here, the method sound is invoked based on the actual subclass (Cat or Dog) of the object,
even though the reference type is Animal.
Compile-time Polymorphism (Overloading)

This occurs when multiple methods in the same class have the same name but differ in:
 The number of parameters
 The types of parameters
 The order of parameters
This is resolved during compile-time.
Example of Method Overloading:
class Calculator {
// Method to add two integers
int add(int a, int b) {
return a + b;
}

// Overloaded method to add three integers


int add(int a, int b, int c) {
return a + b + c;
}

// Overloaded method to add two double numbers


double add(double a, double b) {
return a + b;
}
}

public class Main {


public static void main(String[] args) {
Calculator calc = new Calculator();
System.out.println(calc.add(10, 20)); // Calls add(int, int)
System.out.println(calc.add(10, 20, 30)); // Calls add(int, int, int)
System.out.println(calc.add(10.5, 20.5)); // Calls add(double, double)
}
}
Runtime Polymorphism (Overriding)
 Run-time polymorphism in Java occurs when a subclass provides a specific
implementation of a method that is already defined in its parent class.
 The method to be executed is determined at runtime based on the object's type.
Key Rules for Overriding:
1. The method in the subclass must have the same name, return type, and parameters as
the method in the parent class.
2. The overridden method cannot have stricter access modifiers than the method in the
parent class.
3. The method must be inheritable (not private or final).
Example of Method Overriding:

class Animal {
void sound() {
System.out.println("Animal makes a sound");
}
}

class Dog extends Animal {


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

public class Main {


public static void main(String[] args) {
Animal myAnimal = new Dog(); // Polymorphism: Parent reference, child object
myAnimal.sound(); // Output: Dog barks
}
}
Encapsulation in Java

 Encapsulation is a core principle of Object-Oriented Programming (OOP).


 It controls access to the internal state of an object.
 Implemented in Java using:
o Private fields

o Getter and setter methods

o Access control modifiers

Why Use Encapsulation?


 Data Hiding
o Protects the internal state of an object from external interference and misuse.

 Controlled Access
o Allows controlled modification or retrieval of fields through getter and setter
methods, enabling validation or business logic.
 Flexibility
o Changes in internal implementation do not impact external code.

 Maintaining Integrity
o Ensures fields are modified only in valid ways (e.g., validation in setter
methods).
Private Fields
 Variables declared with the private access modifier.
 Restricts direct access from outside the class.
 Promotes data hiding, ensuring the internal representation of the object is secure.
Example:

public class Person {


private String name; // Private field
private int age; // Private field
}
Getter and Setter Methods
 Getter Methods (also called accessors) allow the outside world to read the values of
private fields.
 Setter Methods (also called mutators) allow the outside world to modify the values
of private fields, but only in a controlled way.
 Getters and setters are often used to enforce validation and business rules when
accessing or modifying private data.
Example:

public class Person {


private String name;
private int age;

// Getter method for 'name'


public String getName() {
return name;
}

// Setter method for 'name'


public void setName(String name) {
this.name = name;
}

// Getter method for 'age'


public int getAge() {
return age;
}

// Setter method for 'age'


public void setAge(int age) {
if (age > 0) {
this.age = age;
} else {
System.out.println("Age must be positive.");
}
}
}

Explanation:
 The getName() method allows access to the private name field.
 The setName() method allows setting a value to the name field.
 The getAge() method allows access to the private age field.
 The setAge() method ensures that only positive values are assigned to age.
Access Control Modifiers

Java provides four main access control modifiers to specify the visibility of classes, fields,
methods, and constructors:
 private: The field, method, or class is accessible only within its own class.
 default (package-private): The field, method, or class is accessible only within its
own package (if no modifier is provided).
 protected: The field, method, or class is accessible within its own package and by
subclasses (even if they are in different packages).
 public: The field, method, or class is accessible from any other class.
Example:

public class Car {


private String model; // private field
public int year; // public field

// Constructor
public Car(String model, int year) {
this.model = model;
this.year = year;
}

// Getter method for 'model'


public String getModel() {
return model;
}

// Setter method for 'model'


public void setModel(String model) {
this.model = model;
}
}

Explanation:
 The model field is private, meaning it can only be accessed within the Car class.
 The year field is public, so it can be accessed from any other class.
Abstraction

Abstraction is a fundamental concept in OOP that simplifies complex systems by:


 Hiding implementation details of an object.
 Exposing only the essential features needed for interaction.
 Focusing on what an object does rather than how it does it.
In Java, abstraction is achieved using:
 Abstract classes
 Interfaces
Abstract Classes
An abstract class is a blueprint for other classes, with the following characteristics:
 It cannot be instantiated directly.
 Can contain:
o Abstract methods: Methods without implementation (no body).

o Concrete methods: Methods with implementation (with a body).

 It can have instance variables and constructors.


 Supports single inheritance (a class can extend only one abstract class).
Syntax:

abstract class Animal {


abstract void sound(); // abstract method

void sleep() { // concrete method


System.out.println("Sleeping...");
}
}

Example:

class Dog extends Animal {


@Override
void sound() {
System.out.println("Bark");
}
}
Interfaces

 An interface in Java acts as a contract specifying the behaviours a class must


implement.
 It can only contain abstract methods (up to Java 7).
 Starting from Java 8, interfaces can also include:
o Default methods (with a body).

o Static methods (with a body).

 A class implementing an interface must provide implementations for all its abstract
methods.
Syntax:
interface Animal {
void sound(); // abstract method
default void sleep() { // default method (Java 8+)
System.out.println("Sleeping...");
}
}
Key Features:
 All methods in an interface are implicitly abstract (except default and static methods).
 Cannot have instance variables (only constants—public static final fields).
 A class can implement multiple interfaces (Java supports multiple inheritance for
interfaces).
 Interfaces are often used to achieve loose coupling between classes.
Example:
class Dog implements Animal {
@Override
public void sound() {
System.out.println("Bark");
}
}
Differences Between Abstract Class and Interface:
When to Use Each?
 Abstract Class:
Use when you want to provide a common base class with shared functionality and enforce
that certain methods are implemented in subclasses.
 Interface:
Use when you want to define a contract that can be implemented by any class,
regardless of its place in the class hierarchy.
JVM

 The JVM (Java Virtual Machine) is a crucial component in the execution of Java
programs.
 It allows Java programs to run on any device or platform by abstracting away the
underlying system's specifics.
 JVM architecture consists of several key components, which together manage the
execution of Java programs.
ClassLoader Subsystem:
 The ClassLoader is responsible for loading class files into the JVM.
 It is a part of the JVM that reads the bytecode of classes and loads them into memory
when needed.
 The ClassLoader is important for dynamic loading of classes and for ensuring that
classes are loaded only once during the execution of a program.
There are different types of class loaders in the JVM:
 Bootstrap ClassLoader: This is the top-level class loader that loads core Java
libraries (e.g., java.lang.*, java.util.*) from the rt.jar file.
 Extension ClassLoader: It loads classes from the JDK's lib/ext directory or any other
specified extension directories.
 System ClassLoader: Also known as the application class loader, it loads classes
from the classpath.
JVM Runtime Data Areas (Simple Explanation)
When a Java program runs, the JVM (Java Virtual Machine) manages memory using different
areas to store different types of data. These areas help Java run efficiently. Here’s a simple
breakdown:
1. Method Area
o Think of this as a "storage room" where Java keeps important details about classes,
such as method definitions, static variables, and constants.
o It helps Java remember how things should work.
2. Heap
o This is where Java stores objects (things created using new).
o Every object and its variables live here as long as they are needed.
o The garbage collector cleans up unused objects.
3. Java Stack
o Each time a method runs, Java creates a stack frame to store things like method
calls and local variables.
o Every thread (small task running in a program) gets its own stack.
o Once a method is finished, its stack frame is removed.
4. Program Counter (PC) Register
o Think of this as a "bookmark" that tells Java which line of code it is executing at
any moment.
o Each thread has its own PC register.
5. Native Method Stack
o Sometimes, Java needs to use code written in other languages like C or C++.
o This stack helps Java manage these native methods separately.
These areas work together to manage memory and run Java programs smoothly.

Execution Engine:
 The Execution Engine is responsible for executing the bytecode of Java programs.
 It interprets or compiles the bytecode into native machine code that can be executed
by the host machine.
The main components of the Execution Engine are:
 Interpreter:
It reads and interprets the bytecode line by line. Although this method is simple, it can be
slow.
 Just-In-Time (JIT) Compiler:
 The JIT compiler improves performance by translating bytecode into native machine
code at runtime.
 The first time a method is called, it is interpreted, but subsequent calls are compiled
into native code for faster execution.
 Garbage Collector:
 The garbage collector automatically manages memory by reclaiming memory that is
no longer in use.
 It helps prevent memory leaks.
Summary of JVM Architecture:
 ClassLoader: Loads class files into memory.
 Runtime Data Areas: Stores method data, objects, local variables, and other
execution-related information.
 Execution Engine: Executes the bytecode by interpreting or compiling it to native
code.
Memory management

 Memory management in Java involves understanding how memory is allocated and


deallocated for variables and objects.
 This process relies on the stack and heap, each serving different purposes in Java's
memory model. Here’s a breakdown:
1. Stack Memory:
 The stack is used for storing method frames (local variables and function calls).
Each time a method is called, a new frame is pushed onto the stack, and when the
method finishes execution, the frame is popped off.
 Local variables, including primitive types (like int, float, etc.), are stored on the
stack.
 The stack operates in a last-in, first-out (LIFO) order.
 Memory management is automatic: when a method finishes execution, its local
variables are automatically discarded.
 The stack is limited in size, so excessive recursion or large local variables can cause
a stack overflow.
2. Heap Memory:
 The heap is used for storing objects and their associated data (fields).
 Unlike the stack, memory management in the heap is more complex, and objects can
exist as long as they are still referenced.
 Objects created using the new keyword (e.g., new MyClass()) are stored in the heap.
 The heap is much larger than the stack and dynamically allocated.
 Garbage collection (GC) is responsible for automatically reclaiming memory in the
heap that is no longer in use. When there are no references to an object, it becomes
eligible for garbage collection.
3. Memory Leaks:
 A memory leak occurs when an application loses track of objects that are still using
memory, preventing the garbage collector from reclaiming that memory.
 This typically happens when references to objects are unintentionally retained. Even if
an object is no longer needed, if references to it still exist, it won’t be garbage
collected.
 In Java, memory leaks are often due to holding onto references in collections or static
fields that are never removed.
 Example of a memory leak: Storing objects in a List and not removing them when
no longer needed.
4. Reference Types:
 In Java, all objects are reference types. This means variables that hold objects do not
store the actual object itself but rather a reference (memory address) to the object.
 Primitive types (like int, boolean, etc.) store actual values, whereas reference types
store references (pointers) to objects in the heap.
 There are different types of references in Java:
o Strong references: The most common type, where objects cannot be garbage
collected if they are strongly referenced.
o Weak references: Objects can be garbage collected if they are weakly
referenced, typically used in caching systems.
o Soft references: Used for memory-sensitive caches where objects are garbage
collected when the JVM is low on memory.
o Phantom references: Used to schedule post-mortem cleanup actions before
an object is garbage collected.
Garbage Collection (GC) in Java

 Garbage Collection (GC) is an automatic memory management process in Java.


 It helps manage memory by reclaiming unused memory (objects) that are no longer
reachable or referenced by the program.
 The primary goal of GC is to prevent memory leaks and ensure efficient memory
usage without requiring manual intervention.
Key Concepts of Garbage Collection:
 Heap Memory
o Memory allocated to objects is part of the heap.

o When an object is created, it is allocated space in the heap.

o The garbage collector cleans up the heap by removing unreachable objects.

 Reachability
o An object is considered reachable if there is a chain of references from:

 Any active thread.


 A static field.
 Another object that can access it.
o Once all references to an object are lost, it becomes unreachable, and the
garbage collector can reclaim its memory.
 Generational Heap
o The heap is divided into multiple regions:

 Young Generation
 Where new objects are created.
 Divided into:
 Eden Space: Where objects are initially allocated.
 Survivor Spaces (S0 and S1): Where objects that
survive garbage collection cycles are moved.
 Old Generation (Tenured)
 Stores objects that have existed longer and are less likely to
become garbage quickly.
 Permanent Generation (or Metaspace in later versions of Java)
 Stores metadata about classes and methods used by the
program.
GC Process:
1. Mark Phase: The garbage collector identifies all reachable objects starting from the
root (active references such as stack, static variables, etc.). Objects that are not
marked are considered garbage.
2. Sweep Phase: Unreachable objects (those not marked) are removed, and their
memory is freed up.
3. Compact Phase (Optional): After objects are swept, the remaining objects are
compacted to reduce fragmentation in memory, making it contiguous again.
Types of Garbage Collectors:

Java provides several garbage collection algorithms, each with different performance
characteristics. They can be broadly categorized into:
1. Serial Garbage Collector:
o Description: Uses a single thread to perform all garbage collection tasks.

o Use Case: Suitable for small applications with limited memory requirements
and in environments with limited CPU resources.
o JVM Option: -XX:+UseSerialGC

2. Parallel Garbage Collector (Throughput Collector):


o Description: Uses multiple threads to perform the garbage collection process,
making it faster than the Serial GC.
o Use Case: Suitable for multi-threaded applications where high throughput is
desired and the application runs on a multi-core processor.
o JVM Option: -XX:+UseParallelGC

3. CMS (Concurrent Mark-Sweep) Garbage Collector:


o Description: Performs most of its work concurrently with the application’s
execution, aiming to minimize application pause times. It has two main
phases: marking and sweeping, with concurrent marking of reachable objects.
o Use Case: Suitable for applications where low pause time is critical, like
large-scale web applications.
o JVM Option: -XX:+UseConcMarkSweepGC

4. G1 Garbage Collector:
o Description: A low-pause-time collector that divides the heap into regions. It
can prioritize certain regions and can be tuned to achieve low pause times and
high throughput. It performs garbage collection in a series of smaller steps
rather than one large pause.
o Use Case: Suitable for applications that require a balance between high
throughput and low pause times.
o JVM Option: -XX:+UseG1GC

5. ZGC (Z Garbage Collector):


o Description: A scalable low-latency garbage collector designed to handle
large heaps with minimal pause times. It uses multiple threads to perform
concurrent marking, sweeping, and compacting.
o Use Case: Ideal for applications with very large heaps (multi-terabyte) and
need to minimize GC pause times.
o JVM Option: -XX:+UseZGC

6. Shenandoah GC:
o Description: Another low-pause-time garbage collector that aims for low
latency and minimal GC pause times. It works similarly to ZGC but is
designed with a different internal architecture.
o Use Case: Applications requiring low latency, such as real-time processing
and low-latency applications.
o JVM Option: -XX:+UseShenandoahGC

GC Tuning:

Tuning garbage collection is essential for optimizing performance, especially for applications
with high memory requirements. Several JVM options can be used to fine-tune GC
behaviour:
1. Heap Size Configuration:
o -Xms<size>: Set the initial heap size.

o -Xmx<size>: Set the maximum heap size.

o These parameters control the overall size of the heap and can significantly
impact GC performance.
2. Young Generation Size:
o -XX:NewSize=<size>: Set the initial size of the young generation.

o -XX:MaxNewSize=<size>: Set the maximum size of the young generation.

o Adjusting the young generation size can affect the frequency of minor garbage
collections.
3. GC Pause Time:
o -XX:MaxGCPauseMillis=<time>: Set the target maximum pause time for
garbage collection.
o -XX:GCTimeRatio=<ratio>: Control the ratio of application time to GC time.

4. GC Logging:
o -XX:+PrintGCDetails: Print detailed GC logs.

o -XX:+PrintGCDateStamps: Print timestamps for GC events.

o -Xlog:gc*:file=<logfile>: To log garbage collection details in a specific file for


analysis.
5. Tuning the G1 Garbage Collector:
o -XX:MaxGCPauseMillis: Set the maximum pause time for G1.

o -XX:G1HeapRegionSize: Set the size of regions in G1.

o -XX:G1NewSizePercent: Controls the percentage of the heap reserved for the


young generation in G1.
6. Thread Control:
o -XX:ParallelGCThreads=<number>: Controls the number of threads used for
parallel garbage collection.
o -XX:ConcGCThreads=<number>: Controls the number of threads for
concurrent marking phases in collectors like CMS and G1.

Option Example Purpose


-Xms<size>& -Xmx<size> -Xms512m -Xmx2g Set heap size
-XX:NewSize=<size> & - -XX:NewSize=256m - Set young generation
XX:MaxNewSize=<size> XX:MaxNewSize=512m size
-XX:MaxGCPauseMillis=<time> -XX:MaxGCPauseMillis=200 Limit GC pause time
Option Example Purpose
Control GC vs app
-XX:GCTimeRatio=<ratio> -XX:GCTimeRatio=9
time
-XX:+PrintGCDetails -XX:
+PrintGCDateStamps
-Xlog:gc*:file=gc.log Enable GC logging
Set max pause for
-XX:MaxGCPauseMillis (G1) -XX:MaxGCPauseMillis=100
G1GC
Define region size
-XX:G1HeapRegionSize -XX:G1HeapRegionSize=8m
for G1
Control parallel GC
-XX:ParallelGCThreads -XX:ParallelGCThreads=8
threads
Control concurrent
-XX:ConcGCThreads -XX:ConcGCThreads=4
marking

Input / Output in Java

Printing in Java:
1. Using println() Method:

Prints text on the console and moves the cursor to the next line.
System.out.println("Coding");
System.out.println("Ninjas");
// Output:
// Coding
// Ninjas
2. Using print() Method:

Prints text on the console without moving to the next line.


System.out.print("Coding");
System.out.print("Ninjas");
// Output: CodingNinjas
3. Using printf() Method:

Prints formatted text.


System.out.printf("PI = %.2f\n", Math.PI); // Output: PI = 3.14
System.out.printf("n = %.4f\n", 5.2f); // Output: n = 5.2000
Example Program:

public class Test {


public static void main(String args[]) {
int age = 21;
String firstName = "King", lastName = "Kong";
System.out.println("My name is " + firstName + " " + lastName);
System.out.println("My age is " + age);
}
}
// Output:
// My name is King Kong
// My age is 21

Key Points:
 Use + for string concatenation.
 println() and print() differ in cursor placement.
 printf() formats output precisely.

Taking Input in Java

In Java, you can take user input primarily through two classes:
1. Scanner Class (in java.util package)
2. BufferedReader Class
1. Using Scanner Class
The Scanner class is commonly used to read input of primitive types (e.g., int, double) and
strings. Import java.util.Scanner to use it.
Methods of Scanner class in Java:

Example :
import java.util.Scanner;
class TakingInputFromUser {
public static void main(String argo[]) {

// Creating an object of Scanner class


Scanner sc = new Scanner(System.in);

// Read integer value from the user


System.out.println(“Enter first number :”);
int a = sc.nextInt();

System.out.println(“Enter second number :”);


int b = sc.nextInt();

// Adding two values


int c = a + b;

// Printing the sum


System.out.println(“Sum is : “ +c);
}
}
//Output
//Enter first number : 10
//Enter second number : 20
//Sum is : 30
2. Using BufferedReader Class

The BufferedReader class in Java is another way to take input from the user. It is more
efficient than the Scanner class for reading large input data and is part of the java.io package.
Steps to Use BufferedReader:
1. Import the java.io package.
2. Create a BufferedReader object using InputStreamReader.
3. Use the readLine() method to read input as a string.
4. Convert the string to other data types (if needed).
Example: Reading an Integer

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

class TakingInputUsingBufferedReader {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

System.out.println("Enter a number:");
int number = Integer.parseInt(br.readLine()); // Convert string to integer

System.out.println("You entered: " + number);


}
}
//Output:
//Enter a number: 25
//You entered: 25

Limitations:
1. Handles only string input; parsing is needed for other data types.
2. Requires exception handling (IOException).
Introduction and Editions of Java
Introduction:
Java is a secure, platform-independent, object-oriented programming language developed by
James Gosling in 1995. It follows the "Write Once, Run Anywhere" (WORA) principle,
allowing compiled code to run on any system with a Java Virtual Machine (JVM).

Editions of Java:
1. Java SE (Standard Edition):
Core Java, used for building desktop applications and defining basic Java
functionality (e.g., APIs for networking, security, and GUI development).
2. Java EE (Enterprise Edition):
Extends Java SE for web-based applications, server-side scripting, and web services
using technologies like HTML, CSS, and JavaScript.
3. Java ME (Micro Edition):
Designed for embedded systems, mobile devices, and wireless gadgets, focusing on
lightweight applications.
4. JavaFX:
Merged with Java SE 8, it creates rich graphical user interfaces (GUI) for desktop and
web applications.
Features of Java
1. Simple: Easy to learn with syntax similar to C++. Unused features like explicit
pointers and operator overloading are removed. Includes automatic garbage
collection.
2. Object-Oriented: Based on OOP concepts like classes, objects, inheritance, and
encapsulation, making development and maintenance easier.
3. Platform Independent: Write once, run anywhere. Java code is compiled into
platform-independent bytecode.
4. Robust: Strong memory management, automatic garbage collection, and exception
handling enhance reliability.
5. Portable: Bytecode can run on any platform.
6. Multithreaded: Supports multiple threads sharing memory, ideal for web and
multimedia applications.
7. Distributed: Enables creating distributed applications using RMI and EJB.
8. Secure: Bytecode is non-readable, enhancing security.
Uses of Java
1. Banking: Used for transaction management.
2. Mobile App Development: Core language for Android applications.
3. Desktop Applications: Create GUI apps using AWT, Swing, or JavaFX.
4. Big Data: Hadoop's MapReduce framework is written in Java.
5. Web Applications: Frameworks like Spring and Hibernate support robust web
development.
JDK, JRE, and JVM

 JDK (Java Development Kit): Provides tools for developing and executing Java
programs. It includes both development tools and the JRE.
 JRE (Java Runtime Environment): Allows you to run Java programs. It includes
libraries and other files used by the JVM at runtime.
 JVM (Java Virtual Machine): Executes Java programs. It is part of both JDK and
JRE, responsible for running Java code line by line.

main() Method in Java

The main() method is where Java program execution begins. Here's a simple example:
public class HelloWorld {
public static void main(String args[]) {
System.out.println("Hello World");
}
}
 public: Makes the method accessible to the JVM from outside the class.
 static: Allows the method to be called without creating an object of the class.
 void: The method doesn't return any value.
 main: The name of the method where execution starts.
 String args[]: An array that can hold command-line arguments passed to the program.

Compile and Run Java Programs

1. Open a text editor (e.g., Notepad).


2. Write your Java program and save it with a .java extension (e.g., HelloWorld.java).
3. Open the command prompt and navigate to the directory where your program is
saved.
4. Compile the program using:
javac HelloWorld.java
5. Run the program using:
java HelloWorld
Comments in Java

Comments are non-executable statements that improve code readability and help with
debugging and maintenance.
Types of Comments:
1. Single-line Comment:
Used for commenting one line.
Syntax: // comment
Example:

// Print "Hello World"


System.out.println("Hello World");
2. Multi-line Comment:
Used for commenting multiple lines.
Syntax: /* comment */
Example:

/* Declare a variable and print its value */


int a = 10;
System.out.println(a);
3. Documentation Comment:
Used to generate documentation for code, especially for projects.
Syntax: /** comment */
Example:

/**
* Calculates the product of four integers.
* @param num1 First parameter
* @param num2 Second parameter
* @return Product of the integers
*/
public int FindPro(int num1, int num2, int num3, int num4) {
return (num1 * num2 * num3 * num4);
}
Operators in Java

Operators in Java perform operations on one, two, or three operands and return a result. The
main types of operators are:
 Arithmetic Operators
 Unary Operators
 Assignment Operators
 Relational Operators
 Logical Operators
 Bitwise Operators
 Ternary Operators
 Instance of Operators
Arithmetic Operators

Arithmetic operators in Java perform basic math operations:


 Addition (+): Adds two numbers.
 Subtraction (-): Subtracts two numbers.
 Multiplication (*): Multiplies two numbers.
 Division (/): Divides two numbers.
 Modulus (%): Returns the remainder of a division.
Example:

public class ArithmeticOperators {


public static void main(String args[]) {
int a = 50, b = 20;

System.out.println("Addition: " + (a + b));


System.out.println("Subtraction: " + (a - b));
System.out.println("Multiplication: " + (a * b));
System.out.println("Division: " + (a / b));
System.out.println("Modulus: " + (a % b));
}
}

Output:

Addition: 70
Subtraction: 30
Multiplication: 1000
Division: 2
Modulus: 10
Unary Operators

Unary operators in Java operate on a single operand to perform operations like incrementing,
negation, or inverting boolean values.
1. Unary Minus (-):
Converts a positive value to negative and vice versa.
Example:

int num1 = 10;


num1 = -num1; // -10
int num2 = -20;
num2 = -num2; // 20
2. Unary NOT (!):
Inverts a boolean value (true to false, and vice versa).
Example:

boolean result = !(10 < 20); // false


3. Increment (++):
Increments a variable by 1.
o Post-increment: After evaluating the variable.

o Pre-increment: Before evaluating the variable.


Example:

4. int num = 10;


5. System.out.println(num++); // 10 (then num becomes 11)
6. System.out.println(++num); // 12
7. Decrement (--):
Decreases a variable by 1.
o Post-decrement: After evaluating the variable.
o Pre-decrement: Before evaluating the variable.
Example:

8. int num = 10;


9. System.out.println(num--); // 10 (then num becomes 9)
10. System.out.println(--num); // 8
11. Bitwise Complement (~):
Returns the one's complement of a number.
Example:

int num = 7;
System.out.println(~num); // -8
Assignment Operators

Assignment operators are used to assign values to variables. Common operators include:
1. +=: Adds the right operand to the left operand and assigns it.

int num = 10;


num += 20; // num = num + 20;
System.out.println(num); // Output: 30
2. -=: Subtracts the right operand from the left and assigns it.

int num = 20;


num -= 10; // num = num - 10;
System.out.println(num); // Output: 10
3. *=: Multiplies the left operand by the right and assigns it.

int num = 10;


num *= 5; // num = num * 5;
System.out.println(num); // Output: 50
4. /=: Divides the left operand by the right and assigns it.

int num = 10;


num /= 2; // num = num / 2;
System.out.println(num); // Output: 5
5. %=: Modulo the left operand by the right and assigns it.

int num = 19;


num %= 2; // num = num % 2;
System.out.println(num); // Output: 1
Relational Operators

Relational operators compare two operands and return a boolean result. They are used in
conditions and loops. Below are the common relational operators:
1. Equal to (==): Checks if two operands are equal.
Example:

System.out.println(10 == 20); // false


2. Not equal to (!=): Checks if two operands are not equal.
Example:

System.out.println(10 != 20); // true


3. Greater than (>): Checks if the first operand is greater.
Example:

System.out.println(10 > 20); // false


4. Greater than or equal to (>=): Checks if the first operand is greater than or equal.
Example:

System.out.println(10 >= 8); // true


5. Less than (<): Checks if the first operand is less.
Example:

System.out.println(10 < 15); // true


6. Less than or equal to (<=): Checks if the first operand is less than or equal.
Example:

System.out.println(10 <= 5); // false


Logical Operators

Logical operators perform operations like AND, OR, and NOT on boolean values, returning
true or false.
1. Logical AND (&&): Returns true if both conditions are true.

int a = 10, b = 20, c = 30;


System.out.println((b > a) && (c > b)); // true
System.out.println((b > a) && (c < b)); // false
2. Logical OR (||): Returns true if at least one condition is true.

System.out.println((b > a) || (c < b)); // true


System.out.println((b < a) || (c < b)); // false
3. Logical NOT (!): Reverses the boolean value.

System.out.println(a != b); // true


System.out.println(a == b); // false
Bitwise Operators

Bitwise operators perform bit-level operations on numbers. The key operators in Java are:
1. Bitwise AND (&):
o Result is 1 only if both bits are 1.
o Example: 6 & 7 → 6

2. Bitwise OR (|):
o Result is 1 if any of the two bits is 1.

o Example: 6 | 7 → 7

3. Bitwise NOT (~):


o Inverts all bits of a number.

o Example: ~6 → -7

4. Bitwise XOR (^):


o Result is 1 if bits are different.

o Example: 6 ^ 7 → 1

5. Left Shift (<<):


o Shifts bits to the left, filling with zeros.

o Example: 8 << 2 → 32

6. Right Shift (>>):


o Shifts bits to the right, filling with the sign bit.

o Example: 8 >> 2 → 2

7. Unsigned Right Shift (>>>):


o Shifts bits to the right, filling with zeros.

o Example: 240 >>> 2 → 60

Note: Left and right shift operators may behave unpredictably with negative numbers or
excessive shifts (e.g., 1 << 33).
Ternary Operator

The ternary operator is a shorthand for if-else, taking three operands:


variable = expression1 ? expression2 : expression3;
If expression1 is true, expression2 is evaluated; otherwise, expression3 is evaluated.
Example:
public class TernaryOperator {
public static void main(String args[]) {
int a = 50, b = 100;
int minimum = (a < b) ? a : b;
System.out.println("Minimum Number = " + minimum);
}
}
// Output: Minimum Number = 50
instanceof Operator

The instanceof operator checks if an object is an instance of a specific class, subclass, or


interface. It returns true or false.
Example:
public class InstanceOfExample {
public static void main(String args[]) {
ParentClass obj1 = new ParentClass();
ChildClass obj2 = new ChildClass();

System.out.println("obj1 is instance of ParentClass = " + (obj1 instanceof ParentClass));


System.out.println("obj1 is instance of ChildClass = " + (obj1 instanceof ChildClass));
System.out.println("obj2 is instance of ChildClass = " + (obj2 instanceof ChildClass));
}
}
class ParentClass {}
interface MyInterface {}
class ChildClass extends ParentClass implements MyInterface {}
Output:
obj1 is instance of ParentClass = true
obj1 is instance of ChildClass = false
obj2 is instance of ChildClass = true
Null Check:
InstanceOfOperator obj = null;
System.out.println(obj instanceof InstanceOfOperator); // false
The operator returns false if the object is null.
Control Statements

In Java, code executes sequentially by default, but control flow statements manage the
execution flow. However, Java offers specific statements to manage and direct the flow of
program execution, known as control flow statements.

Java's control flow statements are categorized into three types:


1. Conditional Statements: It allows a program to make decisions and execute specific
blocks of code based on whether a condition evaluates to true or false.
o if statement

o if-else statement

o nested if-statement

o if-else-if ladder

o switch statement

2. Looping Statements: Iteration statements in Java are used to repeatedly execute a


block of code as long as a specified condition is true.
o do-while loop

o while loop

o for loop

o for-each loop

3. Jump Statements: It is used to transfer control to different parts of a program,


breaking the normal flow of execution.
o break statement

o continue statement

o return statement

if Statement

The if statement evaluates a condition. If the condition is true, the corresponding block of
code is executed.
Syntax:
if (condition) {
// Code to execute if condition is true
}
Example:
int age = 20;
if (age >= 18) {
System.out.println("Eligible to vote");
}
Use Case:
 Checking eligibility (e.g., age verification).
 Validating conditions in simple scenarios.
If-Else Statement
An if-else statement is a control structure that determines which statements to choose based
on a set of conditions.
Syntax:
if (condition) {
// Block executed if condition is true
} else {
// Block executed if condition is false
}
Example:
public class JavaIfElseExample {
public static void main(String[] args) {
int a = 49;
// Determine if 'a' is even or odd
if (a % 2 == 0) {
System.out.println("Even Number");
} else {
System.out.println("Number is odd");
}
}
}
Output:Number is odd
Nested If-Statement

A nested if-statement is an if statement within another if statement. The inner block executes
only if the outer condition is true.
Syntax:
if(condition1) {
// Executes if condition1 is true
if(condition2) {
// Executes if condition2 is true
}
}
Example:
public class JavaNestedIfStatement {
public static void main(String[] args) {
int a = 20;

if (a == 20) {
if (a < 25)
System.out.println("a is smaller than 25");

if (a < 22)
System.out.println("a is smaller than 22 too");
else
System.out.println("a is greater than 25");
}
}
}
Output:
a is smaller than 25
a is smaller than 22 too
If-Else-If Ladder

The if-else-if ladder in Java evaluates conditions sequentially from top to bottom. When a
condition is true, its block executes, and the rest are skipped. If no conditions are true, the
else block (if present) serves as a default. Without an else, no action occurs for false
conditions.
Syntax:
if(condition1) {
// Code for condition1
} else if(condition2) {
// Code for condition2
} else if(condition3) {
// Code for condition3
} else {
// Default code if all conditions are false
}

Example:
public class JavaIfElseIfLadder {
public static void main(String[] args) {
int a = 50;
if (a == 30)
System.out.println("a is 30");
else if (a == 45)
System.out.println("a is 45");
else if (a == 50)
System.out.println("a is 50");
else
System.out.println("a is not present");
}
}
Output:
a is 50
switch Statement

The switch statement evaluates a single variable or expression against multiple possible
values (cases). It executes the block of code corresponding to the matching case.
Syntax:
switch (variable) {
case value1:
// Code for value1
break;
case value2:
// Code for value2
break;
default:
// Code if no cases match
}
Example:
int day = 3;
switch (day) {
case 1:
System.out.println("Monday");
break;
case 2:
System.out.println("Tuesday");
break;
case 3:
System.out.println("Wednesday");
break;
default:
System.out.println("Invalid day");
}
Use Case:
 Menu-driven programs (e.g., selecting options).
 Mapping values like days of the week, grades, or roles.
Do-While Loop

 Executes the loop body at least once because the condition is checked at the end.
 Use when you need to ensure the loop runs at least once.
Syntax:

initialization;
do {
// statements
update_expression;
} while (condition);

Example:

int i = 1;
do {
System.out.print(i + " ");
i++;
} while (i <= 10);
// Output: 1 2 3 4 5 6 7 8 9 10
while Loop

A while loop repeatedly executes a block of code as long as the specified condition is true.

Syntax:

while (condition) {
// Code to execute
}

How It Works:
1. The condition is evaluated.
2. If true, the code inside the loop executes.
3. After execution, the condition is rechecked.
4. The loop stops when the condition becomes false.

Example:

int i = 1;
while (i <= 5) {
System.out.println(i);
i++;
}
// Output: 1 2 3 4 5

Use Cases:
 Repeating tasks until a condition is met.
 Reading data from a source until the end is reached.
For Loop

The for loop in Java is used to execute a block of code a specific number of times, making it
ideal for iterating over sequences or ranges.
Syntax:
for (initialization; condition; update) {
// Code to execute
}
 Initialization: Initializes the loop variable (executed once).
 Condition: Checks whether the loop should continue.
 Update: Updates the loop variable after each iteration.

Example:
for (int i = 1; i <= 5; i++) {
System.out.println(i);
}
// Output: 1 2 3 4 5
Key Points:
 The loop runs until the condition becomes false.
 Useful for definite iterations where the number of repetitions is known.
For-Each Loop

 Simplifies iterating through collections or arrays when the index is not needed.
Syntax:
for (Type element : collection/array) {
// statements
}
Example:
String[] words = {"Coding", "Ninjas", "Welcomes", "You"};
for (String word : words) {
System.out.println(word);
}
// Output:
// Coding
// Ninjas
// Welcomes
// You
break Statement

 Terminates a loop or switch and transfers control to the next statement.


 Labeled break Statement: Exits a specific labeled block or loop directly.
Example:
for(int i = 1; i <= 10; i++) {
if(i == 5) break; // Terminates loop when i = 5
System.out.print(i + " ");
}
// Output: 1 2 3 4

outer: {
inner: {
System.out.println("Before break");
break outer; // Exits the outer block
}
System.out.println("This won't execute");
}
System.out.println("After break");
// Output: Before break
// After break
continue Statement

 Skips the current iteration of a loop.


 Labeled continue: Skips to the next iteration of a specific labeled loop.
Example:
// Regular continue
for(int i = 1; i <= 5; i++) {
if(i == 3) continue;
System.out.print(i + " ");
}
// Output: 1 2 4 5
// Labeled continue
outer:
for(int i = 1; i <= 3; i++) {
for(int j = 1; j <= 3; j++) {
if(i == 2 && j == 2) continue outer;
System.out.println(i + " " + j);
}
}
// Output excludes "2 2"
return Statement

The return statement is used to exit a method and transfer control back to the calling method.
It can optionally pass a value to the caller.
Syntax:
return; // Without returning a value
return value; // With a value
Example:
public class ReturnExample {
public static void main(String[] args) {
displayMessage();
}
public static void displayMessage() {
System.out.println("Hello, World!");
return; // Exits the method
}
}

Key Points:
 The return statement must match the method’s return type.
 It is optional for methods with a void return type.
 Essential for methods that compute and send back results.
return Statement

The return statement is used to exit a method and transfer control back to the calling method.
It can optionally pass a value to the caller.
Syntax:
return; // Without returning a value
return value; // With a value
Example:
public class ReturnExample {
public static void main(String[] args) {
displayMessage();
}

public static void displayMessage() {


System.out.println("Hello, World!");
return; // Exits the method
}
}
Key Points:
 The return statement must match the method’s return type.
 It is optional for methods with a void return type.
 Essential for methods that compute and send back results.

Arrays

An array is a fixed-size collection of elements of the same type stored in contiguous


memory. Each element is accessed via its index, starting from 0.
Types of Arrays
1. Single-Dimensional Array: Stores elements linearly, e.g., int[] arr.
2. Multi-Dimensional Array:
o 2D Arrays: Tabular format with rows and columns, e.g., int[][] arr.

o 3D Arrays: Adds a depth dimension, e.g., int[][][] arr.

Properties of Arrays:
 All elements share the same type and size.
 Stored in contiguous memory locations.
 Base address identifies the first element.
Advantages of Arrays:
 Provide O(1) access time using indices.
 Ideal for organizing related data or multidimensional structures.
 Efficient for quick modifications when the index is known.

Disadvantages of Arrays:
 Fixed size, making dynamic resizing impossible.
 Insertion/deletion is costly due to element shifting.
 Inefficient memory usage if size is over/underestimated.
Example: For an array with base address 200, the address of the element at index 4 is
calculated as:
200 + 4 * sizeof(type).

Static vs Dynamic Arrays

1. Static Arrays:
 Definition: Fixed-size arrays defined during initialization.
o Cannot resize after creation.

o Faster as no resizing operations are needed.

o Limited flexibility for dynamic data.

o Use Case: Storing a fixed list of categories or static resources (e.g., menu
items).
Example:
// Static Array
int[] staticArray = new int[5];
staticArray[0] = 10; // Assigning values
System.out.println(staticArray[0]); // Accessing values

2. Dynamic Arrays:
 Definition: Resizable arrays provided by classes like ArrayList.
o Automatically resizes when adding/removing elements.

o Slower due to resizing overhead.

o Requires import java.util.ArrayList.

o Use Case: Managing dynamic content like user comments, form inputs, or
product listings.
Example:
import java.util.ArrayList;
// Dynamic Array
ArrayList<Integer> dynamicArray = new ArrayList<>();
dynamicArray.add(10); // Adding elements
dynamicArray.add(20);
System.out.println(dynamicArray.get(0)); // Accessing values
dynamicArray.remove(1); // Removing an element
Traversal in an Array

Traversal refers to accessing each element of an array, one by one, either to read or modify
the elements.
Example: Traversing an Array Using a Loop
public class ArrayTraversal {
public static void main(String[] args) {
int[] numbers = {10, 20, 30, 40, 50};

// Traversing using a for loop


for (int i = 0; i < numbers.length; i++) {
System.out.println("Element at index " + i + ": " + numbers[i]);
}

// Traversing using a for-each loop


for (int num : numbers) {
System.out.println(num);
}
}
}
Output:
Element at index 0: 10
Element at index 1: 20
Element at index 2: 30
Element at index 3: 40
Element at index 4: 50
10
20
30
40
50
Key Points:
 Use a for loop for accessing elements with their indices.
 Use a for-each loop for simple iteration when index is not needed.

Searching in an Array

Searching for an element in an array can be done using various algorithms like Linear
Search and Binary Search.
 The most basic one is linear search, where we find an element by traversing each
index from first to last.
 Example:
public class SearchArray {
public static void main(String[] args) {
int[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int target = 7; // Element to search
boolean found = false;

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


if (array[i] == target) {
found = true;
break;
}
}

if (found) {
System.out.println("Item found");
} else {
System.out.println("Item not found");
}
}
}
//Output: Item found
 Time Complexity: O(N).
Use Linear Search for unsorted arrays or small datasets for simplicity.
Insertion of an Element in an Array

Steps:
 Create a new array (if needed) with an increased size to accommodate the new
element.
 Shift elements to the right to create space for the new element.
 Insert the element at the desired index.
Let’s code a program to insert an element in a given array-
int main()
{
int arr[size] = {1, 20, 5, 78, 30};
int element, pos, i;
printf("Enter position and element\n");
scanf("%d%d",&pos,&element);
if(pos <= size && pos >= 0)
{
//shift all the elements from the last index to pos by 1 position to the right
for(i = size; i > pos; i--)
arr[i] = arr[i-1];
//Insert element at the given position
arr[pos] = element;
*/
for(i = 0; i <= size-1; i++)
printf("%d ", arr[i]);
}
else
printf("Invalid Position\n");
return 0;
}
Deletion of an Element in an Array

Steps:
1. Find the index of the element to delete.
2. Shift all elements after the index to the left by one position.
3. Reduce the size of the array (if applicable).
Example: Deleting an element at index 2.
public class DeleteElement {
public static void main(String[] args) {
int[] arr = {10, 20, 30, 40, 50};
int indexToDelete = 2; // Deleting 30

// Shifting elements
for (int i = indexToDelete; i < arr.length - 1; i++) {
arr[i] = arr[i + 1];
}

// Print the updated array


for (int i = 0; i < arr.length - 1; i++) {
System.out.print(arr[i] + " ");
}
}
}
// Output: 10 20 40 50
Time Complexity:
 O(N - i) for deletion at index i (shifting elements).
 O(N) for deleting from the beginning.
 O(1) for deleting from the end.
Time Complexity of Array Operations

1. Accessing Elements:
o O(1): Direct access using indices due to contiguous memory storage.

2. Inserting Elements:
o At the end: O(1) (if space is available).

o At index i: O(N - i) (requires shifting elements).

o At the beginning: O(N) (shift all elements right).

3. Finding Elements:
o O(N): Linear search in the worst case.

4. Deleting Elements:
o From the end: O(1).

o At index i: O(N - i) (requires shifting elements left).

o From the beginning: O(N) (shift all elements left).

Real-Time Examples of Arrays in Coding Problems

1. Data Storage:
Arrays are commonly used to store lists of related data, such as names, email
addresses, or database records, enabling efficient retrieval and manipulation.
2. Matrix Operations:
Arrays represent matrices for mathematical operations like addition, subtraction, or
multiplication, often used in scientific computations and graphics.
3. Counting and Tracking:
Arrays help count occurrences, such as tracking the frequency of letters in a string or
monitoring stock prices over a period.
4. Game Development:
2D arrays are used to create grids for games like chess or tic-tac-toe, enabling easy
representation of game states.
5. Image Processing:
Arrays store pixel data to perform operations like filtering, sharpening, or blurring
images for visual processing.

You might also like