0% found this document useful (0 votes)
38 views54 pages

OOPs Concepts Java 8 Features 1756109993

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

OOPs Concepts Java 8 Features 1756109993

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

OBJECT ORIENTED PROGRAMMING SYSTEM IN JAVA

Ajay Kumar

Java 8
Q:
What is OOPs in java ?
It’s stand for Object-Oriented Programming System (OOPs) .
The study of Class, Object, Encapsulation, Inheritance, Polymorphism, and Abstraction is
collectively known as OOPs.
There is 4 Main OOPs Principles in Java :
1. Encapsulation. 2. Inheritance. 3. Polymorphism. 4. Abstraction .

1 . Encapsulation :
Encapsulation is a process of providing security & controlled access to the most important
component of an object . i.e., data members of an object .
Security can be provided by two steps :
1. Preventing direct access by declaring data members as private .
2. Providing controlled access by using public setters and public getters .

Note:
Setters:- It is a public method that updates or sets the value of data members .
Getter:- It is a public method that reads or returns the value of data members .

Example:-

package com.practice;

public class Encapsulation {

private String empName;


private String empId;
private int empAccountNumber;
private int empAccountPin;

public void setData(String empName, String empId , int empAccountNumber , int empAccountPin) {
this.empName=empName;
this.empId=empId;
this.empAccountNumber=empAccountNumber;
this.empAccountPin=empAccountPin;
}

public String getempName() {


return empName;
}
public String getempId() {
return empId;
}
public int getempAccountNumber() {
return empAccountNumber;
}
public int getempAccountPin() {
return empAccountPin;
} https://www.linkedin.com/in/ajay-kumar-sahni-4a02322b8/
public static void main (String[] args){

Encapsulation encap = new Encapsulation();

encap.setData("Ajay", "WLE123", 1234567890, 1234);

System.out.println(encap.getempName());
System.out.println(encap.getempId());
System.out.println(encap.getempAccountNumber());
System.out.println(encap.getempAccountPin());
}
}
2. Inheritance :
Inheritance is the process of acquiring the properties and behaviour of a class by another class .
Inheritance can be implemented using the extends keyword .
* Types of Inheritance :
There are 6 type of Inheritance :-

1. Single Inheritance (Supported)

2. Multilevel Inheritance (Supported)

3. Hierarchical Inheritance (Supported)

4. Multiple Inheritance (Not supported with classes — only via interfaces)

5. Hybrid Inheritance (Not supported directly — can be achieved via interfaces)

6. Cyclic Inheritance (Not allowed in Java)

1.Single Inheritance ✅ (Supported) :-


One class inherits from one superclass.

Example :

class A {
void displayA() {
System.out.println("Class A method");
}
}
class B extends A {
void displayB() {
System.out.println("Class B method");
}
}
public class Test {
public static void main(String[] args) {
B obj = new B();
obj.displayA();
obj.displayB();
}
}
https://www.linkedin.com/in/ajay-kumar-sahni-4a02322b8/

2. Multilevel Inheritance (Supported) :
A class inherits from a superclass, and another class inherits from that subclass (forming a chain).
→ →
Inheritance chain: A B C.

Example:

package com.practice;

class A {
void displayA() {
System.out.println("A method");
}
}

class B extends A {
void displayB() {
System.out.println("B method");
}
}

class C extends B {
void displayC() {
System.out.println("C method");
}
}
public class JavaPactice {

public static void main(String[] args) {


C obj = new C();
obj.displayA();
obj.displayB();
obj.displayC();
}


}
3. Hierarchical Inheritance (Supported) :
Multiple subclasses inherit from the same superclass.
Example:
class Parent {
void display() { System.out.println("Parent method");
}
}
class Child1 extends Parent {
void child1Method() { System.out.println("Child1 method");
}
}
class Child2 extends Parent {
void child2Method() { System.out.println("Child2 method");
}
}
public class Test {
public static void main(String[] args) {
Child1 c1 = new Child1();
c1.display();
c1.child1Method();

Child2 c2 = new Child2();


c2.display();
c2.child2Method();
}
}

4. Multiple Inheritance ❌ (Not supported with classes — only via interfaces) :


A class inherits from more than one parent class.
❌ Not supported for classes in Java (to avoid ambiguity, but possible with interfaces).

Example:

interface A {

void methodA();
}

interface B {

void methodB();
}

class C implements A, B {

public void methodA() {

System.out.println("Method A");
}
public void methodB() {

System.out.println("Method B");
}
}

public class Test {

public static void main(String[] args) {


C obj = new C();
obj.methodA();
obj.methodB();
}
}

5. Hybrid Inheritance (Not supported directly — can be achieved via interfaces) :-
A combination of two or more (Mix of multiple & multilevel inheritance ) types of inheritance.
(only via interfaces).

Example:

interface A {

void methodA();
}

class B {

void methodB() {

System.out.println("Class B method");
}
}

class C extends B implements A {

public void methodA() {

System.out.println("Interface A method");

}
public class Test {

public static void main(String[] args) {


C obj = new C();
obj.methodB();
obj.methodA();
}
}


6. Cyclic Inheritance (Not Supported) :-
A class cannot inherit from itself (directly or indirectly).

Example:


// class A extends A { } // Compile-time error

// class A extends B { } class B extends A { } //

Note:-
❌ Not supported in Java (compiler error: “cyclic inheritance involving ClassName”).
https://www.linkedin.com/in/ajay-kumar-sahni-4a02322b8/
Types of methods in inheritance :
1. Inherited methods
2. Overridden methods
3. Specialized methods

1. Inherited methods :
An inherited method is one that is passed down from a parent class to a child class without
undergoing any modifications .

This means that the child class can use the code provided by the parent class and the methods
behaviour as defined in the parent class .

The advantage of inherited methods is code reusability .

Example :
class Parent {
void display() {
System.out.println("Parent method");
}
}
class Child extends Parent {
// Inherits display() automatically
}

2. Overridden methods :

When a method is inherited from a parent class and used with modifications in the subclass , it is
referred to as an Overridden method .

This allows the subclass to customize and adapt the inherited method to suit it’s specific
requirements.

When the method is called on an instance of a subclass , the overridden method in the subclass is
executed instead of the method in the parent class .
Example :

class Parent {
void showMessage() {
System.out.println("Message from Parent");
}
}

class Child extends Parent {


@Override
void showMessage() {
System.out.println("Message from Child");
}
}
https://www.linkedin.com/in/ajay-kumar-sahni-4a02322b8/
public class Test {

public static void main(String[] args) {

Parent obj = new Child(); // Upcasting

obj.showMessage(); // Executes Child's method


}
}

3. Specialized methods :

A specialized method is a method that is only present in a child class but not in a parent class .

These methods offer more specific functionality tailored to the requirements of the child class .

The advantage of specialized method is that it increases the feature of child class when compared to
the parent class .

Example :

class Parent {

void display() {

System.out.println("Parent method");
}
}
class Child extends Parent {

void extra() { // Specialized method

System.out.println("Child-specific method");
}
}

https://www.linkedin.com/in/ajay-kumar-sahni-4a02322b8/
3. Polymorphism :
The word Polymorphism comes from Greek — “poly” (many) + “morph” (forms).
👉It means one entity (method/variable/object) behaving in multiple forms.

Types of Polymorphism in Java :


👉 Polymorphism can be achieved in Java in two ways:

1. Compile-time Polymorphism (Method Overloading / Static binding / Early binding )


Achieved using method overloading.
Decision is made at compile-time.
Example:
class Calculator {
// Method Overloading
int add(int a, int b) {
return a + b;
}

double add(double a, double b) {


return a + b;
}
}

public class Test {


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

2. Runtime Polymorphism (Dynamic binding / Method Overriding)


Achieved using Method Overriding + Inheritance + Upcasting.
Decision is made at runtime by the JVM (based on the object’s actual type).
Example:

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

class Dog extends Animal {


@Override
void sound() {
System.out.println("Dog barks");
}
}
class Cat extends Animal {
@Override
void sound() {
System.out.println("Cat meows");
}
}

public class Main {


public static void main(String[] args) {
Animal a1 = new Dog(); // Upcasting
Animal a2 = new Cat();

a1.sound(); // Dog barks (runtime decision)


a2.sound(); // Cat meows (runtime decision)
Q:
Write a Java program to demonstrate runtime polymorphism (method overriding) using the concept of
planes.
Create a parent class Plane with methods:
takeOff()
fly()
land()
Create three child classes:
a. CargoPlane
b. PassengerPlane
c. FighterPlane
Each child class should override the above three methods to provide its own implementation.
In the main method, create objects of each child class but refer to them using a parent class
reference (Plane).
Demonstrate how Java chooses the overridden method at runtime.

Program:

package com.practice;
class Plane{
void takeOff(){
System.out.println("Plane is takeOff");
}
void fly(){
System.out.println("Plane is fly");
}
void land() {
System.out.println("Plane is landing");
}
}
class CargoPlane extends Plane{
void takeOff(){
System.out.println("CargoPlane is takeOff");
}
void fly(){
System.out.println("CargoPlane is fly");
}
void land(){
System.out.println("CargoPlane is landing");
}
}
class PassengerPlane extends Plane{
void takeOff(){
System.out.println("PassengerPlane is takeOff");
}
void fly(){
System.out.println("PassengerPlane is fly");
}
void land(){
System.out.println("PassengerPlane is landing");
}
}
class FighterPlane extends Plane {
void takeOff(){
System.out.println("FighterPlane is takeOff");
}
void fly(){
System.out.println("FighterPlane is fly");
}
void land(){
System.out.println("FighterPlane is landing");
}
}
public class Polymorphisim {
public static void main (String[] args){
Plane cp = new CargoPlane();
Plane pp = new PassengerPlane();
Plane fp = new FighterPlane();
cp.takeOff();
cp.fly();
cp.land();
pp.takeOff();
pp.fly();
pp.land();
fp.takeOff();
fp.fly();
fp.land();
}
The above code has achived polymorphisim but it hasn’t achieved advantages of polymorphisim yet. so
next we will see how to achive code reduction and code flexibility ?

package com.practice;
class Plane {
void takeOff() {
System.out.println("Plane is takeOff");
}
void fly() {
System.out.println("Plane is fly");
}
void land() {
System.out.println("Plane is landing");
}
}

class CargoPlane extends Plane {


@Override
void takeOff() {
System.out.println("CargoPlane is takeOff");
}
@Override
void fly() {
System.out.println("CargoPlane is fly");
}
@Override
void land() {
System.out.println("CargoPlane is landing");
}
}

class PassengerPlane extends Plane {


@Override
void takeOff() {
System.out.println("PassengerPlane is takeOff");
}
@Override
void fly() {
System.out.println("PassengerPlane is fly");
}
@Override
void land() {
System.out.println("PassengerPlane is landing");
}
}

https://www.linkedin.com/in/ajay-kumar-sahni-4a02322b8/
class FighterPlane extends Plane {
@Override
void takeOff() {
System.out.println("FighterPlane is takeOff");
}
@Override
void fly() {
System.out.println("FighterPlane is fly");
}
@Override
void land() {
System.out.println("FighterPlane is landing");
}
}

class Airport {
void permit(Plane ref) {
ref.takeOff();
ref.fly();
ref.land();
}
}

public class Encapsulation {


public static void main(String[] args) {
Plane cp = new CargoPlane();
Plane pp = new PassengerPlane();
Plane fp = new FighterPlane();

Airport a = new Airport();


a.permit(cp);
a.permit(pp);
a.permit(fp);
}
}

Q:
Difference between Tight Coupling and Loose Coupling in Java ?
Tight Coupling :
When a class is heavily dependent on another class and creates its own objects directly.
Hard to maintain because classes are tightly linked.
child reference = child object .

Loose Coupling :
When a class depends on abstractions or receives its dependency from outside instead of creating it.
Easy to maintain as classes are loosely linked.
Parent reference = child object .
Tight Coupling :
Example :
class Engine {
void start() {
System.out.println("Engine starting...");
}
}

class Car {
Engine engine = new Engine(); // Car creates its own Engine (tight coupling)

void drive() {
engine.start();
System.out.println("Car is driving...");
}
}

public class Main {


public static void main(String[] args) {
Car car = new Car(); // Car already tied to Engine
car.drive();
}
}

👉 Problem:
If tomorrow we want an ElectricEngine, we must change Car’s code.

Car is dependent on Engine tight coupling.

Loose Coupling :
Example :
package com.practice;
class WritingTool {
void write() {
System.out.println("Writing something...");
}
}

class Pen extends WritingTool {


void write() {
System.out.println("Writing with a Pen");
}
}

class Pencil extends WritingTool {


void write() {
System.out.println("Writing with a Pencil");
}
} https://www.linkedin.com/in/ajay-kumar-sahni-4a02322b8/
class Student {
void startWriting( WritingTool tool){ // Parent type reference
tool.write();
}
}

public class Encapsulation {

public static void main (String[] args){


WritingTool wp = new Pen(); // upcasting
WritingTool wpn = new Pencil();

Student st = new Student ();


st.startWriting(wp);
st.startWriting(wpn);

}
}

Q:
What’s difference between Upcasting and Downcasting in Java ?
Upcasting :
Converting a child class object into a parent class reference.
Happens automatically (implicit).
Used to achieve runtime polymorphism.
Example :
class Plane {
void fly() {
System.out.println("Plane is flying");
}
}

class CargoPlane extends Plane {


void fly() {
System.out.println("CargoPlane is flying");
}
void carryGoods() {
System.out.println("CargoPlane carries goods");
}
}

public class Test {


public static void main(String[] args) {

Plane p = new CargoPlane(); // Upcasting (Child Parent)
p.fly(); // Calls CargoPlane's fly() [runtime polymorphism]

// p.carryGoods(); // Not allowed (parent reference can't see child-specific methods)
}
}
Downcasting :
Converting a parent class reference back to a child class reference.
Must be done explicitly (manual cast).
Used when you want to access child-specific methods.
Example :
public class Test {
public static void main(String[] args) {
Plane p = new CargoPlane(); // Upcasting
CargoPlane cp = (CargoPlane) p; // Downcasting
cp.fly(); // Works
cp.carryGoods(); // Now accessible
}
}

Q:
What’s differences between method overloading and method overriding ?
Method Overloading :
It is a process of creating multiple methods with same name inside a class but with different
parameters .

Rules:
Must change parameters (number or type).
Return type can be same or different (if parameters differ).
Can be in the same class or child class.

Method Overriding :
The process of inheriting a method from the parent class and changing the body of the method is
known as method overriding .

Rules:
Must have same method signature (name + parameters).
Return type must be same or covariant (subtype).
Access modifier cannot be more restrictive.
Only inherited methods can be overridden.
final, static, and private methods cannot be overridden.

🔹 Method Hiding in Java :


When a subclass defines a static method with the same name and signature as a static method in
its superclass, the method in the subclass hides the superclass method.
👉 This is called Method Hiding.

🔑 Key Points:
Applies only to static methods.
It’s not runtime polymorphism (like overriding).
Method call is resolved at compile-time, based on the reference type, not the object.
Non-static methods cannot be hidden, they can only be overridden.
🔹 Example: Method Hiding
class Parent {
static void display() {
System.out.println("Parent static method");
}
}

class Child extends Parent {


static void display() { // Hides Parent's method
System.out.println("Child static method");
}
}

public class MethodHidingDemo {


public static void main(String[] args) {
Parent p = new Parent();
p.display(); // Output: Parent static method

Child c = new Child();


c.display(); // Output: Child static method

Parent ref = new Child();


ref.display(); // Output: Parent static method (compile-time binding)
}
}

🔑 Difference Between Method Hiding vs Method Overriding ?


Aspect Method Hiding (Static) Method Overriding (Non-Static)

Method Type Only for static methods Only for instance methods

Binding Compile-time binding Runtime binding

Polymorphism Not achieved Achieved

Execution depends On reference type On object type

Keyword static Non-static methods only


4. Abstraction :

Abstraction is the process of hiding implementation details and showing only the essential features
of an object.

It focuses on what an object does, not how it does it.

In Java, abstraction can be achieved using two way :

a. Abstract Classes (0–100% abstraction)


b. Interfaces (100% abstraction before Java 8, but from Java 8 onwards, interfaces can have default
& static methods, so they are not strictly 100%).

First we will achived abstraction using Abstract class .


Example :
abstract class BankAccount {
abstract void accountType(); // Abstract method
abstract double rateOfInterest();

// Concrete method (common logic)


void showBankRules() {
System.out.println("All accounts must follow RBI rules.");
}
}

class SavingsAccount extends BankAccount {


@Override
void accountType() {
System.out.println("This is a Savings Account");
}

@Override
double rateOfInterest() {
return 4.5;
}
}

class CurrentAccount extends BankAccount {


@Override
void accountType() {
System.out.println("This is a Current Account");
}

@Override
double rateOfInterest() {
return 2.5;
}
} https://www.linkedin.com/in/ajay-kumar-sahni-4a02322b8/
public class AbstractionDemo {

public static void main(String[] args) {

BankAccount acc1 = new SavingsAccount(); // upcasting (loose coupling )


acc1.accountType();
System.out.println("ROI: " + acc1.rateOfInterest() + "%");
acc1.showBankRules();

BankAccount acc2 = new CurrentAccount();


acc2.accountType();
System.out.println("ROI: " + acc2.rateOfInterest() + "%");
}
}
Q:
Can we create a constructor in an abstract class in Java?

✅ Yes, we can create a constructor in an abstract class.


But remember:
We cannot directly instantiate an abstract class (i.e., new AbstractClass() is not allowed).
The constructor of the abstract class is invoked when a subclass object is created.
The main use of a constructor in an abstract class is to initialize common fields or perform setup
tasks needed by all subclasses.
Example :
abstract class BankAccount {
String accountNumber;
String accountHolder;

// Constructor in abstract class


BankAccount(String accountNumber, String accountHolder) {
this.accountNumber = accountNumber;
this.accountHolder = accountHolder;
System.out.println("BankAccount constructor: Initialized common details");
}

// Abstract method (must be implemented by child classes)


abstract void accountType();

// Concrete method (common for all accounts)


void showDetails() {
System.out.println("Account Holder: " + accountHolder + ", Account Number: " + accountNumber);
}
}
class SavingsAccount extends BankAccount {
SavingsAccount(String accountNumber, String accountHolder) {
super(accountNumber, accountHolder); // Call to abstract class constructor
System.out.println("SavingsAccount constructor: Additional setup for savings account");
}
@Override
void accountType() {
System.out.println("This is a Savings Account");
}
}

class CurrentAccount extends BankAccount {


CurrentAccount(String accountNumber, String accountHolder) {
super(accountNumber, accountHolder);
System.out.println("CurrentAccount constructor: Additional setup for current account");
}

@Override
void accountType() {
System.out.println("This is a Current Account");
}

public class BankDemo {


public static void main(String[] args) {
BankAccount acc1 = new SavingsAccount("SA12345", "Ajay");
acc1.showDetails();
acc1.accountType();

System.out.println();

BankAccount acc2 = new CurrentAccount("CA54321", "Kumar");


acc2.showDetails();
acc2.accountType();
}
}
Q:
You are asked to design a simple Airport Management System in Java using the concept of Abstraction
and Polymorphism.
1. Create an abstract class Plane with three abstract methods:
takeOff()
fly()
land()
2. Implement three types of planes:
CargoPlane
PassengerPlane
FighterPlane
Each should provide its own implementation of takeOff(), fly(), and land().
3. Create an Airport class with a method permit(Plane ref) which should call all three methods
(takeOff, fly, land) on the given Plane object.
4. Extension Task (for extra points):
Add a new class PrivateJet (a luxury plane) and show that your design still works without
changing the Airport class code.
package com.practice;

abstract class Plane {

abstract void takeOff();


abstract void fly();
abstract void land();
}

class CargoPlane extends Plane {

void takeOff(){
System.out.println("CargoPlane is takingOff");
}

void fly() {
System.out.println("CargoPlane is flying");
}

void land() {
System.out.println("CargoPlane is landing");
}

}
class PassengerPlane extends Plane {

void takeOff() {
System.out.println("PassengerPlane is takingOff");
}

void fly() {
System.out.println("PassengerPlane is flying");
}

void land() {
System.out.println("PassengerPlane is landing");
}

}
class FighterPlane extends Plane {

void takeOff() {
System.out.println("FighterPlane is takingOff");
}

void fly() {
System.out.println("FighterPlane is flying");
}
void land() {
System.out.println("FighterPlane is landing");
}
}

class Airport{
static void permit(Plane ref) {
ref.takeOff();
ref.fly();
ref.land();
}
}

public class Abstraction {

public static void main (String[] args) {

Plane cp = new CargoPlane();


Plane pp = new PassengerPlane();
Plane fp = new FighterPlane();

Airport.permit(cp);
Airport.permit(pp);
Airport.permit(fp);

}
}

Note :
Abstract Class : Restricted class which cannot be used to create objects .

Abstract Method : Method with just signature and no body .

An Abstract class can not be instantiated .

A class with atleast one abstract method must be declared as abstract .

An abstract class can contain only concrete methods as well .

Abstract and final keywords cannot be used together .

An Abstract class can inherit from another abstract class .

An Normal class can inherit form an Abstract class .

An Abstract class can inherit from a Normal class .


Q:
Why can’t abstract and final be used together in Java?
Ans:
Reason 1: Contradictory Nature
abstract → says “this method/class must be overridden/extended by subclasses.”
final→ says “this method/class cannot be overridden/extended.”
👉 Putting them together creates a direct contradiction.
It’s like saying:
“You must override this method, but you cannot override it.” 🚫
Reason 2: For Methods
abstract class Test {

abstract final void show(); // Compilation Error
}
abstract → method has no body, subclass must provide implementation.
final → prevents subclass from overriding.

Hence, it makes no sense compiler throws error.

✅ Reason 3: For Classes


final abstract class Shape { } // ❌ Compilation Error
abstract class →
must be inherited to provide implementations.
final class →cannot be inherited.

Again contradictory, so not allowed.


Q:
Why abstract class cannot be instantiated?
✅ In Java
An abstract class is like a blueprint.
It may have unfinished parts (abstract methods without body).
Java says:
You cannot create an object from a blueprint (abstract class).
But you can create objects from the actual house (subclass that completes all the details).
abstract class Vehicle {
abstract void start(); // No body (unfinished)
}
class Car extends Vehicle { 👉
So hence “An abstract class cannot be
void start() { instantiated because it is incomplete — it may
System.out.println("Car starts with a key"); contain abstract methods without implementations.
} Just like you can’t live in a blueprint of a house,
} you can’t create an object of an abstract class. Only
public class Test { its concrete subclass can be instantiated.”
public static void main(String[] args) {

// Vehicle v = new Vehicle(); Not allowed
Vehicle v = new Car(); ✅
// Allowed
v.start();
👉
} //Note: Vehicle is just a concept (blueprint).
} 👉 Car is a real object you can use. https://www.linkedin.com/in/ajay-kumar-sahni-4a02322b8/
Achieved Abstraction using Interface :
Q:
What is an Interface ?
An interface is a collection of pure abstract methods ; inside an interface , you have only method
with a signature without body .
A class that implements an interface must provide implementations for all its abstract methods.

Example :
interface ATMCard {
void withdraw(double amount);
void deposit(double amount);
}

class HDFCBank implements ATMCard {


@Override
public void withdraw(double amount) {
System.out.println("Withdraw " + amount + " using HDFC system");
}

@Override
public void deposit(double amount) {
System.out.println("Deposit " + amount + " into HDFC account");
}
}

class SBIBank implements ATMCard {


@Override
public void withdraw(double amount) {
System.out.println("Withdraw " + amount + " using SBI system");
}

@Override
public void deposit(double amount) {
System.out.println("Deposit " + amount + " into SBI account");
}
}
public class BankDemo {
public static void main(String[] args) {
ATMCard card1 = new HDFCBank();
card1.withdraw(5000);

ATMCard card2 = new SBIBank();


card2.deposit(2000);
}
}
Q: “What happens if you remove @Override?”
👉 Say: “Code will still run if signatures match, but you lose compile-time safety. That’s why
professional developers always use @Override.”
Rules of an Interface : Total 11 rules is available an interface in java :

Rules 1: An interface is like a contract which when implemented helps to achieve Standardization .
Example :
👉 RBI is like an interface.
👉 Banks are like classes implementing the interface.
RBI (Interface) says: “You must follow verifyCustomer() , provideLoan(), transferFunds() methods.”
Banks (Classes) must implement these methods, otherwise compiler error.
Customers (Users) can always rely that all banks will provide these standard services.
👉 This is exactly how Interfaces enforce standardization in Java.
Program :

package com.practice;
interface RBI {
void verifyCustomer();
void provideLoan();
void transferFunds();
}

//HDFC Bank must follow RBI rules(means Standardization)


class HDFCBank implements RBI {

public void verifyCustomer() {


System.out.println("HDFC verifies customer via Aadhaar");
}
public void provideLoan() {
System.out.println("HDFC provides Loan with 10% interest");
}
public void transferFunds() {
System.out.println("HDFC allows NEFT/IMPS/RTGS transfers");
}
}

//SBI Bank must also follow RBI rules(means Standardization)


class SBIBank implements RBI {

public void verifyCustomer() {


System.out.println("SBI verifies customer via PAN");
}

public void provideLoan() {


System.out.println("SBI provides Loan with 9% interest");
}

public void transferFunds() {


System.out.println("SBI allows UPI and NetBanking transfers");
}
}
https://www.linkedin.com/in/ajay-kumar-sahni-4a02322b8/
public class BankDemo {

public static void main(String[] args) {


RBI bank1 = new HDFCBank(); // RBI reference (loose coupling )
RBI bank2 = new SBIBank(); // RBI reference (loose coupling )

bank1.verifyCustomer();
bank1.provideLoan();
bank1.transferFunds();

bank2.verifyCustomer();
bank2.provideLoan();
bank2.transferFunds();
}
}

Rules 2 : Interfaces promotes Polymorphisim . An interfaces type reference can point to implementing
class objects . This achieves loose coupling , code reduction and code flexibility .

Q: Why Interfaces Promote Polymorphism ?


👉 Interfaces promote polymorphism because a single interface reference can point to multiple
implementing class objects.

Rules 3 : Methods within an interface are automatically public and abstract .

Notes :
All methods in an interface are automatically public and abstract (till Java 7).
This means:
You don’t need to write public abstract explicitly.
Even if you don’t write them, the compiler adds it.
Example:

interface Shape {

void draw(); // compiler treats as → public abstract void draw();


}

✅ But from Java 8 onwards → interfaces can also have:


default methods (with body).
static methods (with body).
private methods (from Java 9, only for internal use in interface).

👉 “By default, interface methods are public and abstract, but since Java 8, interfaces can also have
default, static, and (from Java 9) private methods.”

https://www.linkedin.com/in/ajay-kumar-sahni-4a02322b8/
Rule 4 : Specialized methods cannot be accessed directly using interface type references .
Note :
“Specialized methods cannot be accessed directly using an interface reference because the reference is
restricted to the contract of the interface. To access them, we need downcasting.”

Example :

interface Vehicle {
void start();
}

class Car implements Vehicle {


public void start() {
System.out.println("Car starts");
}
public void openTrunk() { // Specialized method
System.out.println("Trunk opened");
}
}

public class Test {


public static void main(String[] args) {
Vehicle v = new Car(); // Interface reference
v.start(); ✅
// Allowed (declared in interface)

// v.openTrunk(); // ❌ Error (not part of interface)


// To access specialized method:
Car c = (Car) v; // Downcasting
c.openTrunk(); ✅
// Now accessible
}
}
Rule 5 : If a class partially implements interface , it must declare itself as abstract .
Note :
“If a class partially implements an interface, it must be declared abstract because it has left some
methods unimplemented. Only a subclass can complete those remaining methods.”
Example :
interface Payment {
void pay();
void refund();
}

// Class partially implements (only one method)


abstract class CardPayment implements Payment {
public void pay() {
System.out.println("Payment done using Card");
}

// refund() is not implemented so class must be abstract
}
// Concrete class must finish the job
class VisaCard extends CardPayment {
public void refund() {
System.out.println("Refund processed to VisaCard");
}
}

public class Test {


public static void main(String[] args) {
Payment p = new VisaCard();
p.pay();
p.refund();
}
}
Rule 6 : A class can implements multiple interfaces because diamond shape problem does not exist as
interfaces will not have parents .

Example :

interface A {
void show();
}

interface B {
void show();
}

class C implements A, B {


// Must implement show() removes ambiguity
public void show() {
System.out.println("Implemented show() once in class C");
}
}

public class Test {


public static void main(String[] args) {
C obj = new C();
obj.show();
}
}

Note:
both A and B have the same method signature → void show();
So class C implements both at once by giving just one show() method.

That’s why I didn’t write a separate method — it’s automatically valid for both interfaces.
Example With Different Methods (Clearer) :

interface A {
void show();
}

interface B {
void display();
}

class C implements A, B {

// Implements method from A


public void show() {
System.out.println("Show() from interface A");
}

// Implements method from B


public void display() {
System.out.println("Display() from interface B");
}
}

public class Test {

public static void main(String[] args) {

C obj = new C();


obj.show();
obj.display();
}
}

Note :

3️⃣ Why Diamond Problem Doesn’t Exist?

If two interfaces have same method signatures, you implement it once.

If two interfaces have different methods, you implement all of them.

No confusion → because class C is always in control of implementation.


✅ Interview Punchline:
“When a class implements multiple interfaces, it must implement all methods. If method signatures
overlap, one implementation covers both, removing ambiguity and avoiding the diamond problem.”
Rule 7 : An interface cannot implements another interface , because interface cannot provide methods
with bodies inside it .
Example :
interface A {
void show();
}

interface B implements A { // Not allowed (Compilation Error)
void display();
}
Note :
🔎 Why?
The compiler expects extends between interfaces, not implements.

Because implements means provide method body, but interfaces cannot provide method bodies
(except default/static).
So Java grammar rules don’t even allow it.
Rule 8 : An interface can extend another interface . Not only this it can inherit from multiple interface
because the diamond shape problem does not exist .

Note : This works fine because interfaces only define method signatures, not state or implementation
→ so diamond problem doesn’t exist.
Example :
interface A {
void show();
}
interface B {
void display();
}

interface C extends A, B { // multiple inheritance
void print();
}
class D implements C {
public void show() {
System.out.println("Show() from A");
}
public void display() {
System.out.println("Display() from B");
}
public void print() {
System.out.println("Print() from C");
}
}
public class Test {
public static void main(String[] args) {
C obj = new D();
obj.show();
obj.display();
obj.print();
}
} https://www.linkedin.com/in/ajay-kumar-sahni-4a02322b8/
Q : How to achieve multiple inheritance via interface ?
📌
For Scenario: Online Payment Gateway System
Authenticate the User (from Authentication interface)
Process Transactions (from Transaction interface)
Generate Reports (from Report interface) .
Program :
interface Authentication { // Interface for user authentication
void authenticateUser(String username, String password);
}
interface Transaction { // Interface for transaction processing
void processPayment(double amount);
}
interface Report { // Interface for reporting
void generateReport();
}
// Multiple inheritance with interface
interface PaymentProcessor extends Authentication, Transaction, Report {
void refund(double amount);
}
// Concrete class implementing all methods
class RazorPayProcessor implements PaymentProcessor {
@Override
public void authenticateUser(String username, String password) {
System.out.println("User " + username + " authenticated successfully.");
}
@Override
public void processPayment(double amount) {
System.out.println("Payment of ₹" + amount + " processed via RazorPay.");
}
@Override
public void generateReport() {
System.out.println("Transaction report generated.");
}
@Override
public void refund(double amount) {
System.out.println("Refund of ₹" + amount + " initiated.");
}
}
public class PaymentApp {
public static void main(String[] args) {
PaymentProcessor processor = new RazorPayProcessor();
processor.authenticateUser("ajay", "secure@123");
processor.processPayment(1500.00);
processor.generateReport();
processor.refund(500.00);
}
}
Note : Multiple inheritance in java can be indirectly achieved by making use of inheritance .
Rule 9 : A class can both extends another class as well as implement an interface . However order
should be extend first and implemented later .
Example :
class Vehicle { // Parent class
void fuelType() {
System.out.println("Runs on petrol/diesel.");
}
}
interface Electric { // Interface 1
void charge();
}
interface SelfDriving { // Interface 2
void autoPilot();
}
// Child class (Extends + Implements)
class TeslaCar extends Vehicle implements Electric, SelfDriving {
@Override
public void charge() {
System.out.println("Tesla is charging with electricity.");
}
@Override
public void autoPilot() {
System.out.println("Tesla is driving in autopilot mode.");
}
}
public class Demo {
public static void main(String[] args) {
TeslaCar car = new TeslaCar();
car.fuelType(); // Inherited from Vehicle
car.charge(); // From Electric interface
car.autoPilot(); // From SelfDriving interface
}
}
Note :
A class can extend another class (single inheritance).
A class can implement one or multiple interfaces (multiple inheritance via interfaces).

But the order is fixed
Syantax :
class ChildClass extends ParentClass implements Interface1, Interface2 { }

❌ Wrong Syntax (implements before extends) :


class ElectricCar implements Electric, GPS extends Vehicle {
// Compilation Error
}

❌ You cannot write implements ... extends ... → It will give a compilation error.
Rule 10 : An interface can contain constant variables and method signatures . A variable within an
interface is automatically public static final .

Example :

interface Bank {
// Automatically public static final
double INTEREST_RATE = 7.5;

void provideLoan();
}

class SBI implements Bank {


@Override
public void provideLoan() {
System.out.println("SBI provides loan at " + INTEREST_RATE + "% interest.");
}
}

public class TestBank {


public static void main(String[] args) {
System.out.println("Bank Standard Rate: " + Bank.INTEREST_RATE);
Bank bank = new SBI();
bank.provideLoan();
}
}
Note :
👉 In Java, variables declared in an interface are by default public, static, and final. This means they act
as constants, shared across all implementing classes. They help in defining standard values that remain
the same everywhere (e.g., tax rates, interest rates, error codes).

Rule 11 : An empty interface in java is referred to as a Marker interface or Tagged interface .


It is used to provide special properties to the object of the class .

Note :
An empty interface (no methods, no fields) is called a Marker Interface.

Purpose →
It does not define behavior but instead marks a class with special meaning so that JVM
or frameworks can provide special treatment.

It’s like putting a tag on a class.

🔹 Examples of Marker Interfaces in Java


1. Serializable (inbuilt interface )→ Marks that objects of a class can be serialized (converted into byte
stream).

2. Cloneable → Marks that objects of a class can be cloned using Object.clone().


3.Remote → Marks that objects can be accessed remotely (used in RMI).
Example :

import java.io.Serializable;

class Employee implements Serializable {


int id;
String name;

Employee(int id, String name) {


this.id = id;
this.name = name;
}
}

public class MarkerInterfaceDemo {

public static void main(String[] args) {

Employee emp = new Employee(101, "Ajay");

// Check if Employee is marked as Serializable


if (emp instanceof Serializable) {

System.out.println("Employee object can be Serialized!");

} else {

System.out.println("Employee object cannot be Serialized!");


}
}
}

Note :
A Marker Interface is an empty interface used to “mark” a class so that JVM or frameworks can
recognize it and provide special behavior. Examples are Serializable, Cloneable, and Remote.

Thank you .

https://www.linkedin.com/in/ajay-kumar-sahni-4a02322b8/
Java 8 Feature :
Q:
What is a Default Method in Java 8 ?

A default method is a method inside an interface that has a body (implementation).


Declared with the default keyword.

👉 Example:
interface Vehicle {
void start(); // abstract method

default void honk() { // default method


System.out.println("Beep Beep!");
}
}
class Car implements Vehicle {
public void start() {
System.out.println("Car starting...");
}
}
public class Test {
public static void main(String[] args) {
Vehicle v = new Car();
v.start(); // Car starting...
v.honk(); // Beep Beep!
}
}
Q:
Why were Default Methods Introduced in Java 8?
🔹 Problem Before Java 8

Interfaces could not have method bodies only abstract methods.
If you added a new method to an interface, then all classes implementing it broke, because they
were forced to implement that new method.
👉 Example (Pre-Java 8):

interface Vehicle {
void start();
}

// Later you add:


interface Vehicle {
void start();

void stop(); // all old classes now break
}

Note :If 100+ classes implement Vehicle, then all 100 need to implement stop(), even if they don’t need
it. This was a major backward compatibility problem for APIs like Collection, List, Map.
Java 8 Solution → Default Method
By introducing default methods (with body inside interface), new functionality could be added without
breaking existing classes.

👉 Example:
interface Vehicle {
void start();


default void stop() { // safe, backward compatible
System.out.println("Vehicle stopped.");
}
}

✅ Interview Answer
“Default methods were introduced in Java 8 to solve the problem of backward compatibility in
interfaces. Before Java 8, adding a new method to an interface broke all implementing classes. With
default methods, new methods can be added with a body, so existing implementations continue to
work without modification.”

Q:
What is a Static Method in Java 8 (in Interfaces) and why it’s not inherited by implemented class ?

From Java 8, interfaces can also declare static methods with a body.
These methods belong only to the interface itself.
They are not inherited by implementing classes (because of these methods belongs to interface
itself).

👉 Example:
interface Vehicle {
static void info() {
System.out.println("Vehicle Info: General method");
}
}

class Car implements Vehicle {


void start() {
System.out.println("Car starting...");
}
}

public class Test {


public static void main(String[] args) {
Vehicle.info(); // ✅Works

// Car.info(); // Error: not inherited
}
}
Q:
Why Static Methods get not overridden in Classes ?
Static methods in classes are inherited by subclasses.
But they are not polymorphic (they don’t override, only hide).

👉 Example:
class Parent {
static void greet() {
System.out.println("Hello from Parent");
}
}

class Child extends Parent {


static void greet() { // hiding, not overriding
System.out.println("Hello from Child");
}
}

public class Test {


public static void main(String[] args) {
Parent.greet(); // Parent version
Child.greet(); // Child version
}
}
🔹 Methods in Classes vs Interfaces (Java 8+)
Feature Class Interface (Java 8+)
Abstract Methods Can exist in abstract class only. Must Default in interfaces before Java 8. Still
be implemented by subclass. allowed (must be implemented by class).

Default Methods ❌ Not allowed in classes. ✅ Introduced in Java 8. Have body.


Support backward compatibility & API
evolution.

✅ Allowed. Inherited by subclass, ✅ Allowed from Java 8. Not inherited by


Static Methods implementing class. Must be called via
but only hidden (not overridden).
InterfaceName.method()

Instance Methods ✅ Normal methods with body. ❌ Not allowed (only default/abstract).
Final Methods ✅ Allowed (cannot be overridden ❌ Not applicable (interfaces can’t have
in subclass). final methods).

Private Methods ✅ Allowed (normal use). ✅ Introduced in Java 9, only for helper
code inside interface.
Q:
What is a Private Method in an Interface (Java 9)?

From Java 9, an interface can have private methods (both normal and static).

These are helper methods that can be used inside the interface to avoid code duplication
(redundant code).

They are not inherited by implementing classes.

👉 Example:
package com.practice;
interface Student {
static void personalLife() {
System.out.println("--- Personal Life ---");
redundantCode(); // reusing private static method
}

static void professionalLife() {


System.out.println("--- Professional Life ---");
redundantCode(); // reusing private static method
}

private static void redundantCode() { // private static helper method (Java 9 feature)
System.out.println("Student will wake-up with mobile ");
System.out.println("Student will do some activity with mobile ");
System.out.println("Student will do breakfast with mobile ");
System.out.println("Student will sleep with mobile ");
}
}

public class Interface {


public static void main(String[] args) {

Student.personalLife(); // Calling static methods from interface


System.out.println();
Student.professionalLife();
}
}

🔹 Types of Private Methods in Interfaces (Java 9)


1. Private Instance Method → used inside default methods.
private void log(String msg) { ... }


2. Private Static Method used inside other static/default methods.
private static void helper() { ... }
Q:
What is Functional Interface ?
A Functional Interface is an interface with exactly one abstract method.
It can have any number of default or static methods.
Used in Lambda expressions, Method references, and Streams API.
Annotation @FunctionalInterface is optional but recommended.
Example :
@FunctionalInterface
interface MyFunctional {
void show();
}
Q:
How many Ways to Implement a Functional Interface ?
There is 5 way to implements Functional Interface .
1. Regular/Normal Class
2. Inner Class
3. Anonymous Class
4. Lambda Expression (Java 8+)
5. Method Reference (::)
1. Regular/Normal Class :
A regular class implements the functional interface and provides the body for its abstract method.
Example :
@FunctionalInterface
interface MyFunctional {
void show();
}
class MyClass implements MyFunctional { // Regular class implementing functional interface
public void show() {
System.out.println("Implemented using Regular Class");
}
}
public class Test1 {
public static void main(String[] args) {
MyFunctional obj = new MyClass(); // object of normal class
obj.show();
}
}
2. Inner Class :
An inner class (non-static class inside another class) implements the functional interface.
Example : }
@FunctionalInterface }
interface MyFunctional { public static void main(String[] args) {
void show(); Test2 outer = new Test2();// create outer object
} //create inner class object
public class Test2 { MyFunctional obj = outer.new Inner();
// Inner class implementing functional interface obj.show();
class Inner implements MyFunctional { }
public void show() { }
System.out.println("Implemented using Inner Class");
3. Anonymous Inner Class :
An anonymous inner class implements the functional interface without creating a separate class
file. It is declared and instantiated at the same time.
Example :

@FunctionalInterface
interface MyFunctional {
void show();
}

public class Test3 {


public static void main(String[] args) {
// Anonymous class
MyFunctional obj = new MyFunctional() {
public void show() {
System.out.println("Implemented using Anonymous Class");
}
};
obj.show();
}
}
4. Lambda Expression Implementation (Java 8+) :
A lambda expression is a shorthand way to provide implementation for a functional interface.
👉 Syntax: (parameters) -> expression
Example :

@FunctionalInterface
interface MyFunctional {
void show();
}

public class Test4 {


public static void main(String[] args) {
// Lambda Expression
MyFunctional obj = () -> System.out.println("Implemented using Lambda Expression");
obj.show();
}
}
5. Method Reference (::) Implementation (Java 8+) :
A method reference is used to refer to an existing method by its name instead of writing a lambda.
👉 Syntax: ClassName::methodName
Example :

@FunctionalInterface
interface MyFunctional {
void show();
}
public class Test5 {

public static void displayMessage() {


System.out.println("Implemented using Method Reference");
}

public static void main(String[] args) {


// Method Reference (::)
MyFunctional obj = Test5::displayMessage;
obj.show();
}
}
Q :“How does the Stream API calculate the sum of all integers in the list using
mapToInt(Integer::intValue).sum()?”

package com.practice;
import java.util.Arrays;
import java.util.List;

public class MethodReferenceExample {

public static void main(String[] args) {


List<Integer> data = Arrays.asList(10,20,13,15);
int result = data.stream().mapToInt(Integer :: intValue).sum();
System.out.println(result);

}
}
Q :“How does the Stream API find the maximum element from the list using max(Integer::compareTo)
and why does it return an Optional?”

package com.practice;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

public class MethodReferenceExample {

public static void main(String[] args) {


List<Integer> numbers = Arrays.asList(10,20,13,15);
Optional<Integer> max = numbers.stream().max(Integer :: compareTo);

// for finding the mininum value form the given Arrays


// Optional<Integer> min = numbers.stream().min(Integer :: compareTo);
// System.out.println(min.get());
System.out.println(max.get());
}
}
Types of Functional Interfaces :
1. Custom Functional Interface → created by us (MyFunctional).
2. Predefined Functional Interfaces (from java.util.function) →
Predicate<T>
Function<T, R>
Consumer<T>
Supplier<T>
And many more (BiFunction, UnaryOperator, etc.)

1. Custom Functional Interface :


Created by developers.

Example :

@FunctionalInterface
interface MyFunctional {
void show();
}

2. Predefined Functional Interfaces (Java 8, java.util.function) :

1. Predicate functional Interface :


It is a predefined functional interface in java.util.function package .
It takes one input, compares or checks a condition, and returns a boolean value (true/false).

Example : 1

package com.practice;

import java.util.function.Predicate;

public class PredicateExample {

public static void main(String[] args) {

Predicate<Integer> val = x -> x > 300; // Lambda

boolean result = val.test(100);

System.out.println(result); // false

}
}
Example : 2

package com.practice;
import java.util.function.Predicate;

public class PredicateExample {

public static void main(String[] args) {


Predicate<String> val = x->x.equals("mike");
boolean result = val.test("mike");
System.out.println(result); // true
}
}
Predicate Functional Interface is used to Filtering the record .
Example : 1

package com.practice;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class PredicateExample {

public static void main(String[] args) {


List<Integer> data = Arrays.asList(100,10,35,2,15,500,700);
List<Integer>newData = data.stream().filter(x->x>100).collect(Collectors.toList());
System.out.println(newData); // output : 500 , 700
}
}

Note :
stream() : It will peak the data one by one from Array List and work applying a logic .

Example : 2

package com.practice;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class PredicateExample {

public static void main(String[] args) {


List<String> data = Arrays.asList("mike","adam","madam","bike","mama");
List<String> newData = data.stream().filter(x->x.startsWith("m")).collect(Collectors.toList());
System.out.println(newData); // mike , madam , mama
}
}
Q:
Write a Java program to filter even numbers from a list using Predicate and Stream API.
package com.practice;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class PredicateExample {

public static void main(String[] args) {

List<Integer> data = Arrays.asList(10,11,13,14,16,19);


List<Integer> newData = data.stream().filter(x -> x % 2 == 0).collect(Collectors.toList());
System.out.println(newData);
}
}
Q:
Write a Java program to filter odd numbers from a list using Predicate and Stream API.
package com.practice;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class PredicateExample {

public static void main(String[] args) {

List<Integer> data = Arrays.asList(10,11,13,14,16,19);


List<Integer> newData = data.stream().filter(x -> x % 2 != 0).collect(Collectors.toList());
System.out.println(newData);
}
}
Q:
Write a Java program using Stream API and Predicate to filter out all strings whose length is greater
than 4.
package com.practice;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class PredicateExample {

public static void main(String[] args) {

List<String> data = Arrays.asList("mike","stallin","adam");


List<String> newData = data.stream().filter(s->s.length()>4).collect(Collectors.toList());
System.out.println(newData);
}
}
2. Function Functional Interface :

Function<T, R> is a predefined functional interface in java.util.function package.


It takes one input of type T and produces one output of type R.
Method signature: R apply(T t);

Function<T, R> takes input, returns any type R (used for transformation/mapping).
👉 So yes✅ Function is not for filtering, but for transforming data.

Example :
Q: Write a Java program using the Function functional interface to calculate the length of a given string.
package com.practice;
import java.util.function.Function;
public class FunctionExample {

public static void main(String[] args) {


Function<String , Integer> x = s->s.length();
Integer val = x.apply("mike");
System.out.println(val); // output : 4
}
}
Q: Write a Java program using the Function functional interface to calculate the square of a given
number.
package com.practice;
import java.util.function.Function;

public class FunctionExample {

public static void main(String[] args) {


Function<Integer , Integer> x = s->s*s;
Integer val = x.apply(100);
System.out.println(val);
}
}
Q: Write a Java program using Stream API and the map() function to generate a list containing the
squares of given integers.
package com.practice;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class FunctionExample {

public static void main(String[] args) {


List<Integer> data = Arrays.asList(10,20,30);
List<Integer> newData = data.stream().map(x->x*x).collect(Collectors.toList());
System.out.println(newData);
}
}
Q:
Write a Java program using Stream API and the map() function to increase each number in a list by 5.
package com.practice;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class FunctionExample {

public static void main(String[] args) {

List<Integer> data = Arrays.asList(10,20,30);


List<Integer> newData = data.stream().map(x->x+5).collect(Collectors.toList());
System.out.println(newData);
}
}
Q: Write a Java program using Stream API and the map() function to convert all strings in a list to
uppercase.
package com.practice;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class FunctionExample {

public static void main(String[] args) {

List<String> data = Arrays.asList("mike","ajay","adam");


List<String> newData = data.stream().map(x->x.toUpperCase()).collect(Collectors.toList());
System.out.println(newData); // output : MIKE , AJAY , ADAM
}
}
Q:
Write a Java program using Stream API and the map() function to find the length of each string in a list.
package com.practice;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class FunctionExample {

public static void main(String[] args) {

List<String> data = Arrays.asList("mike","ajaykumar","adamchacha");


List<Integer> newData = data.stream().map(x->x.length()).collect(Collectors.toList());
System.out.println(newData); // output :4, 9, 10
}
}
Q: Write a Java program using Stream API to sort a list of strings in ascending order.
package com.practice;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class FunctionExample {

public static void main(String[] args) {


List<String> data = Arrays.asList("mike","ajaykumar","adamchacha");
List<String> newData = data.stream().sorted().collect(Collectors.toList());
System.out.println(newData);
}
}

Q: Write a Java program using Stream API to remove duplicate elements from a list of strings.
package com.practice;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class FunctionExample {


public static void main(String[] args) {

List<String> data = Arrays.asList("mike","stallin","adam","mike","stallin");


List<String> newData = data.stream().distinct().collect(Collectors.toList());
System.out.println(newData);
}
}
Q: Write a Java program using Stream API to fetch only the first 3 elements of a list and also
demonstrate how to skip the first 2 elements.
package com.practice;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class LimitExample {


public static void main(String[] args) {
List<Integer> data = Arrays.asList(10, 20, 30, 40, 50, 60);

// Take only first 3 elements


List<Integer> limited = data.stream().limit(3).collect(Collectors.toList());
System.out.println(limited); // Output: [10, 20, 30]

// Skip first 2 elements


List<Integer> skipped = data.stream().skip(2).collect(Collectors.toList());
System.out.println(skipped); // Output: [30, 40, 50, 60]
}
}
3. Consumer Functional Interface :
The Consumer<T> functional interface is part of java.util.function package.

It takes a single input (of type T) but does not return any output.

Instead, it performs an operation (like printing, logging, saving, etc.) on the given input.

Its abstract method is : void accept(T t);

Example :
Q:
Demonstrate the use of the Consumer functional interface in Java by writing a program that accepts a
string input and prints a customized greeting message.
package com.practice;
import java.util.function.Consumer;

public class ConsumerExample {

public static void main(String[] args) {

// Consumer that prints a string


Consumer<String> consumer = s -> System.out.println("Hello, " + s);

consumer.accept("Ajay"); // Output: Hello, Ajay


consumer.accept("Mike"); // Output: Hello, Mike
}
}

Q:
Write a Java program using the Consumer functional interface and forEach() method to print all
elements of a list.

package com.practice;

import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;

public class ConsumerExample {

public static void main(String[] args) {

List<String> names = Arrays.asList("Alice","Bob","charl");


Consumer<String> val = s->System.out.println(s);
names.forEach(val); // Alice , Bob , charl
}
}
1. What is Stream API in Java?
The Stream API (introduced in Java 8) is used to process collections of objects in a functional
programming style.
It does not store data, it only processes data from sources (like Collections, Arrays, I/O).
It supports filtering, mapping, reducing, sorting, collecting, etc.
It allows parallel execution for better performance.

A Stream is not a data structure.


👉 It is a sequence of elements (like a pipeline) that allows you to perform operations such as filtering,
mapping, sorting, and reducing, in a clean and readable way.

2. Why Stream API?

Before Java 8, processing collections required loops + logic (imperative style), which often made
code lengthy and hard to read.

With Stream API, you can write declarative code: what you want rather than how to do it.

3. Key Features of Streams :


Works with Collections and Arrays

Uses functional style (lambda expressions)

Supports pipeline operations (chaining methods)

Provides parallel processing (better performance with large data)

Does not modify original data (immutable operations)

Operations are lazy (executed only when needed)

4. Stream Operations :

There are two types of operations:

(A) Intermediate Operations (return a Stream again) :

→ filters elements based on condition


filter()

map() → transforms each element

sorted() → sorts elements

distinct() → removes duplicates

limit(n) / skip(n) → slicing the stream

👉 These are lazy → they don’t execute until a terminal operation is applied.
(B) Terminal Operations (produce result and end the stream) :

collect()→ collect into List, Set, Map


forEach() → iterate elements

reduce() → reduce into single value (sum, max, etc.)

count() → count elements

min() / max() → find smallest or largest element

5. Example without Streams :

import java.util.*;
public class WithoutStreamExample {
public static void main(String[] args) {
List<String> names = Arrays.asList("Ajay", "Rahul", "Ankit", "Mike", "John");

// Find names that start with "A" and convert to uppercase


List<String> result = new ArrayList<>();
for (String name : names) {
if (name.startsWith("A")) {
result.add(name.toUpperCase());
}
}
System.out.println(result); // [AJAY, ANKIT]
}
}
6. Example with Streams :

import java.util.*;
import java.util.stream.Collectors;

public class WithStreamExample {


public static void main(String[] args) {
List<String> names = Arrays.asList("Ajay", "Rahul", "Ankit", "Mike", "John");

List<String> result = names.stream()


.filter(name -> name.startsWith("A")) // Intermediate
.map(String::toUpperCase) // Intermediate
.collect(Collectors.toList()); // Terminal

System.out.println(result); // [AJAY, ANKIT]


}
}
Write a program with the help of stream api to find employees earning more than ₹50,000 and sort them
by salary.

Program :

import java.util.*;
import java.util.stream.*;

class Employee {
String name;
int salary;

Employee(String name, int salary) {


this.name = name;
this.salary = salary;
}
public String getName() { return name; }
public int getSalary() { return salary; }
}

public class EmployeeStreamExample {

public static void main(String[] args) {

List<Employee> employees = Arrays.asList(


new Employee("Ajay", 70000),
new Employee("Rahul", 40000),
new Employee("Mike", 90000),
new Employee("John", 50000)
);

List<String> highEarners = employees.stream()


.filter(e -> e.getSalary() > 50000)
.sorted(Comparator.comparing(Employee::getSalary))
.map(Employee::getName)
.collect(Collectors.toList());

System.out.println(highEarners); // [Ajay, Mike]


}
}
Q:Write a program with the help of Stream API and filter employees with salary greater than 4000 in
this program, and what happens to the original list after filtering?”

package com.practice;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

class Employee {

private long id ;
private String name ;
private int salary;

public Employee(long id, String name, int salary) {


super();
this.id = id;
this.name = name;
this.salary = salary;
}
public long getId() {
return id;
}
public String getName() {
return name;
}
public int getSalary() {
return salary;
}
}
public class StreamApiExample {
public static void main(String[] args) {
List<Employee> data = Arrays.asList(
new Employee(1,"mike",5000),
new Employee(2, "stallin" , 4000),
new Employee(3, "adam" , 7000)
);

List<Employee> newData = data.stream()


.filter(e -> e.getSalary() > 4000)
.collect(Collectors.toList());

for(Employee emp : newData) {


System.out.println(emp.getId());
System.out.println(emp.getName());
System.out.println(emp.getSalary());
}
}
}
Q:
“How does the Stream API filter employees whose names start with ‘m’ ?

package com.practice;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class EmployeeData {


private long id ;
private String name ;
private int salary;

public EmployeeData(long id, String name, int salary) {


super();
this.id = id;
this.name = name;
this.salary = salary;
}
public long getId() {
return id;
}
public String getName() {
return name;
}
public int getSalary() {
return salary;
}

public static void main(String[] args) {


List<EmployeeData> data = Arrays.asList(
new EmployeeData(1,"mike",5000),
new EmployeeData(2, "stallin" , 4000),
new EmployeeData(3, "adam" , 7000)
);

List<EmployeeData> newData = data.stream()


.filter(e -> e.getName().startsWith("m"))
.collect(Collectors.toList());

for(EmployeeData emp : newData) {


System.out.println(emp.getId());
System.out.println(emp.getName());
System.out.println(emp.getSalary());
}
}
}
Q:
“How can you group employees by their salary using the Stream API?”

package com.practice;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class EmployeeData {


private long id ;
private String name ;
private int salary;

public EmployeeData(long id, String name, int salary) {


super();
this.id = id;
this.name = name;
this.salary = salary;
}
public long getId() {
return id;
}
public String getName() {
return name;
}
public int getSalary() {
return salary;
}

public static void main(String[] args) {


List<EmployeeData> data = Arrays.asList(
new EmployeeData(1,"mike",5000),
new EmployeeData(2, "stallin" , 4000),
new EmployeeData(3, "adam" , 7000)
);

Map<Integer, List<EmployeeData>> newData = data.stream()


.collect(Collectors.groupingBy(e->e.getSalary()));
System.out.println(newData);
}
}

You might also like