Java 8 β†’ Lambda & Functional Interface

πŸ”· Functional Interface

Deep Revision Guide β€” Code + Explanation + Quiz

πŸ“–

Functional Interface kya hota hai?

Core concept samajhte hain β€” step by step

🎯 Simple Definition

Functional Interface = exactly 1 abstract method wala interface.


Java 8 se pehle β€” ek method implement karne ke liye bhi poora anonymous class likhni padti thi. Bahut zyada code. Java 8 ne Lambda Expression diya β€” jisse usi ek abstract method ko bahut short mein likh sakte ho.

⚑ Anonymous Class β†’ Lambda (Evolution)

// PEHLE β€” Anonymous Class (zyada code)
Greet g = new Greet() {
    public void sayHello() {
        System.out.println("Hello!");
    }
};

// AB β€” Lambda (clean & short)
Greet g = () -> System.out.println("Hello!");

Dono same kaam karte hain β€” Lambda sirf short form hai!

RULE 01

SAM β€” Exactly 1 abstract method hona chahiye (Single Abstract Method)

RULE 02

@FunctionalInterface annotation optional hai, but best practice hai β€” compiler check karta hai

RULE 03

default, static, private methods kitne bhi ho sakte hain β€” abstract count nahi hote

RULE 04

toString(), equals(), hashCode() β€” Object ke methods count nahi hote

πŸ’‘ Yaad raho: Lambda expression ek functional interface ka instance create karta hai β€” ye anonymous class ka hi chota roop hai. JVM ke andar same bytecode generate hota hai (approximately).

πŸ”’ Lambda Syntax Quick Reference

// No param
() -> System.out.println("Hi");

// One param β€” brackets optional
x -> x * 2

// Two params β€” brackets must
(a, b) -> a + b

// Multi-line β€” curly braces aur return chahiye
(a, b) -> {
    int result = a + b;
    return result;
}

// Single line return β€” automatic (return mat likho)
(a, b) -> a + b
1️⃣

Program 1 β€” Basic Functional Interface

File: BasicFunctional.java

🎯 Is Program Mein Kya Seekhenge?

  • Apna khud ka Functional Interface banana
  • Anonymous Class vs Lambda β€” dono compare karna
  • default method aur static method kaise kaam karte hain
  • Single param mein brackets optional hoti hain
BasicFunctional.java Program 01
🧩 Explanation: Humne Greet naam ka FI banaya jisme 1 abstract method sayHello() hai. Phir ise 3 tarike se implement kiya β€” Anonymous Class, Lambda (brackets ke saath), aur Lambda (brackets ke bina). Default aur static method bhi call kiye.
@FunctionalInterface
interface Greet {
    void sayHello(String name); // 1 abstract method β€” yahi lambda implement karega

    // default method allowed β€” abstract count nahi hota
    default void sayBye(String name) {
        System.out.println("Bye, " + name + "!");
    }

    // static method allowed
    static void info() {
        System.out.println("This is Greet interface.");
    }
}

public class BasicFunctional {
    public static void main(String[] args) {

        // ===== Tarika 1: Anonymous Class (purana, verbose) =====
        Greet g1 = new Greet() {
            public void sayHello(String name) {
                System.out.println("Hello, " + name + "! (Anonymous Class)");
            }
        };
        g1.sayHello("Rahul");

        // ===== Tarika 2: Lambda with brackets =====
        Greet g2 = (name) -> System.out.println("Hello, " + name + "! (Lambda)");
        g2.sayHello("Amit");

        // Default method bhi call ho sakta hai lambda object se
        g2.sayBye("Amit");

        // Static method β€” interface name se call hota hai
        Greet.info();

        // ===== Tarika 3: Lambda, single param β€” brackets optional =====
        Greet g3 = name -> System.out.println("Namaste, " + name + "!");
        g3.sayHello("Priya");
    }
}
β–Ά Output
Hello, Rahul! (Anonymous Class) Hello, Amit! (Lambda) Bye, Amit! This is Greet interface. Namaste, Priya!

πŸ”‘ Key Points

  • @FunctionalInterface likh do β€” agar galti se 2 abstract methods likhoge to compiler error dega
  • default method call karne ke liye lambda object chahiye (g2.sayBye())
  • static method ke liye interface name use karo (Greet.info())
  • Single param mein (name) aur name β€” dono same hain
2️⃣

Program 2 β€” Lambda Variations

File: LambdaVariations.java

🎯 Is Program Mein Kya Seekhenge?

  • 0, 1, 2 parameters wale lambdas
  • Return karne wale lambdas (single-line vs multi-line)
  • Curly braces kab zaruri hain aur kab nahi
LambdaVariations.java Program 02
🧩 Explanation: 4 alag-alag FIs banaye β€” NoParam, OneParam, TwoParam, WithReturn. Har ek ke liye alag lambda syntax dekha. Multi-line lambda mein curly braces aur explicit return likhna padta hai.
@FunctionalInterface
interface NoParam {
    void show(); // koi param nahi, kuch return nahi
}

@FunctionalInterface
interface OneParam {
    void print(String msg); // ek param, return nahi
}

@FunctionalInterface
interface TwoParam {
    int add(int a, int b); // do param, int return karo
}

@FunctionalInterface
interface WithReturn {
    String greet(String name); // String return karo
}

public class LambdaVariations {
    public static void main(String[] args) {

        // No parameter β€” empty brackets must
        NoParam n = () -> System.out.println("No param lambda!");
        n.show();

        // One parameter β€” brackets optional
        OneParam op = msg -> System.out.println("Message: " + msg);
        op.print("Hello World");

        // Two parameters β€” brackets must | single line = auto return
        TwoParam tp = (a, b) -> a + b;
        System.out.println("Add: " + tp.add(10, 20));

        // Multi-line lambda β€” curly braces + explicit return
        TwoParam multiply = (a, b) -> {
            System.out.println("Multiplying " + a + " and " + b);
            return a * b; // return keyword ZARURI hai curly braces ke andar
        };
        System.out.println("Multiply: " + multiply.add(5, 4));

        // Return String β€” single line
        WithReturn wr = name -> "Hello, " + name + "!";
        System.out.println(wr.greet("Java"));

        // Multi-line with return
        WithReturn wr2 = name -> {
            String result = "Dear " + name;
            return result.toUpperCase(); // DEAR WORLD banayega
        };
        System.out.println(wr2.greet("world"));
    }
}
β–Ά Output
No param lambda! Message: Hello World Add: 30 Multiplying 5 and 4 Multiply: 20 Hello, Java! DEAR WORLD

⚑ Lambda Rules Summary

  • 0 params β†’ () likhna ZARURI hai
  • 1 param β†’ brackets optional β€” x ya (x) dono chalega
  • 2+ params β†’ brackets must β€” (a, b)
  • Single line β†’ return automatic, return mat likho
  • Multi-line curly braces β†’ return keyword ZARURI
3️⃣

Program 3 β€” Predefined Functional Interfaces

File: PredefinedFI.java | Package: java.util.function

🎯 4 Main Predefined FIs

InterfaceMethodInputOutputUse
Predicate<T> test(T t) Tboolean Condition check karo
Function<T,R> apply(T t) TR Transform karo
Consumer<T> accept(T t) Tvoid Use karo, return mat karo
Supplier<T> get() nothingT Sirf value do
PredefinedFI.java Program 03
🧩 Explanation: Java ne already 4 common patterns ke liye FIs bana diye hain β€” Predicate (condition), Function (transform), Consumer (use only), Supplier (produce only). Inhe import karke seedha use karo β€” apna FI banana nahi padta!
import java.util.function.Predicate;
import java.util.function.Function;
import java.util.function.Consumer;
import java.util.function.Supplier;

public class PredefinedFI {
    public static void main(String[] args) {

        // ===== 1. Predicate<T> β€” boolean test(T t) =====
        // Condition check karta hai β€” true ya false return karta hai
        Predicate<Integer> isEven = n -> n % 2 == 0;
        Predicate<String> isLong = s -> s.length() > 5;

        System.out.println("=== Predicate ===");
        System.out.println("10 even? " + isEven.test(10));   // true
        System.out.println("7 even? " + isEven.test(7));     // false
        System.out.println("'Hello' long? " + isLong.test("Hello"));       // false (5 chars, not >5)
        System.out.println("'Hello World' long? " + isLong.test("Hello World")); // true

        // ===== 2. Function<T, R> β€” R apply(T t) =====
        // Input lo, kuch karo, output do (transform)
        Function<String, Integer> strLen = s -> s.length();
        Function<Integer, Integer> square = n -> n * n;

        System.out.println("\n=== Function ===");
        System.out.println("Length of 'Java': " + strLen.apply("Java")); // 4
        System.out.println("Square of 5: " + square.apply(5));             // 25

        // ===== 3. Consumer<T> β€” void accept(T t) =====
        // Input lo, kuch karo β€” return NAHI karta
        Consumer<String> printer = s -> System.out.println("Printing: " + s);
        Consumer<Integer> doubler = n -> System.out.println("Double: " + (n * 2));

        System.out.println("\n=== Consumer ===");
        printer.accept("Hello Consumer!");
        doubler.accept(10);

        // ===== 4. Supplier<T> β€” T get() =====
        // Koi input nahi β€” sirf output deta hai
        Supplier<String> greeting = () -> "Good Morning!";
        Supplier<Double> randomNum = () -> Math.random();

        System.out.println("\n=== Supplier ===");
        System.out.println(greeting.get());
        System.out.println("Random: " + randomNum.get());
    }
}
β–Ά Output
=== Predicate === 10 even? true 7 even? false 'Hello' long? false 'Hello World' long? true === Function === Length of 'Java': 4 Square of 5: 25 === Consumer === Printing: Hello Consumer! Double: 20 === Supplier === Good Morning! Random: 0.7364...
🧠 Trick: Predicate = test karo | Function = badlo | Consumer = khao, return mat karo | Supplier = do, input mat lo
4️⃣

Program 4 β€” Runnable & Comparator

File: BuiltinFI.java

🎯 Is Program Mein Kya Seekhenge?

  • Runnable β€” Thread ke saath Lambda use karna
  • Comparable β€” Natural sorting (String, Integer)
  • Comparator β€” Custom sorting Lambda se (ascending, descending, by length)
BuiltinFI.java Program 04
🧩 Explanation: Runnable ek FI hai (method: run()) β€” Thread banane mein use hota hai. Comparator bhi FI hai (method: compare(T o1, T o2)) β€” custom order mein sort karne ke liye. Lambda se dono bahut clean bante hain.
import java.util.ArrayList;
import java.util.Collections;

public class BuiltinFI {
    public static void main(String[] args) throws InterruptedException {

        // ===== 1. Runnable β€” Thread ke saath =====
        // Runnable ek FI hai β€” void run() β€” 1 abstract method

        // Purana tarika (verbose)
        Runnable r1 = new Runnable() {
            public void run() {
                System.out.println("Thread 1 running (Anonymous Class)");
            }
        };

        // Lambda tarika β€” same kaam, 1 line mein
        Runnable r2 = () -> System.out.println("Thread 2 running (Lambda)");

        Thread t1 = new Thread(r1);
        Thread t2 = new Thread(r2);
        t1.start();
        t2.start();
        t1.join();  // wait karo t1 finish ho jaye
        t2.join();

        // ===== 2. Comparable β€” String natural sorting =====
        ArrayList<String> names = new ArrayList<>();
        names.add("Rahul"); names.add("Amit");
        names.add("Priya"); names.add("Zara");

        System.out.println("\nBefore sort: " + names);
        Collections.sort(names); // String implements Comparable β€” alphabetical order
        System.out.println("After sort: " + names);

        // ===== 3. Comparator β€” custom sorting with Lambda =====
        // Comparator<T> FI hai β€” int compare(T o1, T o2)
        ArrayList<Integer> numbers = new ArrayList<>();
        numbers.add(50); numbers.add(10);
        numbers.add(80); numbers.add(30);

        System.out.println("\nBefore: " + numbers);

        // Ascending β€” (a - b) = positive matlab a bada = a ko peeche rakho
        Collections.sort(numbers, (a, b) -> a - b);
        System.out.println("Ascending: " + numbers);

        // Descending β€” (b - a) = ulta
        Collections.sort(numbers, (a, b) -> b - a);
        System.out.println("Descending: " + numbers);

        // String length ke hisaab se sort
        Collections.sort(names, (a, b) -> a.length() - b.length());
        System.out.println("By length: " + names);
    }
}
β–Ά Output
Thread 1 running (Anonymous Class) Thread 2 running (Lambda) Before sort: [Rahul, Amit, Priya, Zara] After sort: [Amit, Priya, Rahul, Zara] Ascending: [10, 30, 50, 80] Descending: [80, 50, 30, 10] By length: [Amit, Zara, Rahul, Priya]

πŸ”‘ Comparator Logic

  • (a, b) β†’ a - b = Ascending (chota pehle)
  • (a, b) β†’ b - a = Descending (bada pehle)
  • (a, b) β†’ a.length() - b.length() = Choti string pehle
  • Rule: agar result negative β†’ a pehle | positive β†’ b pehle | 0 β†’ equal
5️⃣

Program 5 β€” Real World Use + Error Demo

File: RealWorld.java

🎯 Is Program Mein Kya Seekhenge?

  • Method mein FI parameter ki tarah pass karna
  • Calculator, Validator, Converter real use cases
  • @FunctionalInterface error β€” agar 2 abstract methods likho to kya hoga
  • List filter karna Predicate ke saath
RealWorld.java Program 05
🧩 Explanation: FIs ko method parameters ki tarah pass kiya β€” yahi FI ki asli power hai. calculate(10, 5, add) β€” same method ko alag-alag operations ke saath use kiya. Validator se email/phone validate kiya. Converter mein default method ka use dikhaya.
import java.util.function.Predicate;
import java.util.ArrayList;

// Custom FI 1 β€” Calculator operations ke liye
@FunctionalInterface
interface MathOperation {
    int operate(int a, int b);
}

// Custom FI 2 β€” Validation ke liye
@FunctionalInterface
interface Validator {
    boolean validate(String input);
    // boolean check(); ← Ye uncomment karo to COMPILE ERROR!
    // Error: Validator is not a functional interface
}

// Custom FI 3 β€” Converter with default method
@FunctionalInterface
interface Converter {
    String convert(int number);

    // default method β€” abstract count nahi hota
    default void printConverted(int n) {
        System.out.println("Converted: " + convert(n));
    }
}

public class RealWorld {

    // FI ko method parameter ki tarah receive karo β€” yahi power hai!
    static int calculate(int a, int b, MathOperation op) {
        return op.operate(a, b);
    }

    static void filterAndPrint(ArrayList<String> list, Predicate<String> condition) {
        for (String s : list) {
            if (condition.test(s)) {
                System.out.println("Passed: " + s);
            }
        }
    }

    public static void main(String[] args) {

        MathOperation add = (a, b) -> a + b;
        MathOperation sub = (a, b) -> a - b;
        MathOperation mul = (a, b) -> a * b;

        System.out.println("=== Calculator ===");
        System.out.println("Add: " + calculate(10, 5, add));
        System.out.println("Sub: " + calculate(10, 5, sub));
        System.out.println("Mul: " + calculate(10, 5, mul));
        // Inline lambda bhi de sakte hain directly
        System.out.println("Div: " + calculate(10, 5, (a, b) -> a / b));

        // Validator β€” email aur phone check
        Validator emailVal = email -> email.contains("@") && email.contains(".");
        Validator phoneVal = phone -> phone.length() == 10;

        System.out.println("\n=== Validator ===");
        System.out.println("test@gmail.com valid? " + emailVal.validate("test@gmail.com"));
        System.out.println("testgmail.com valid? " + emailVal.validate("testgmail.com"));
        System.out.println("9876543210 valid? " + phoneVal.validate("9876543210"));
        System.out.println("98765 valid? " + phoneVal.validate("98765"));

        // Converter β€” number ko binary/hex mein badlo
        Converter toBinary = n -> Integer.toBinaryString(n);
        Converter toHex = n -> Integer.toHexString(n);

        System.out.println("\n=== Converter ===");
        toBinary.printConverted(10);  // default method use kiya
        toHex.printConverted(255);

        // List filter karna
        ArrayList<String> names = new ArrayList<>();
        names.add("Rahul"); names.add("Amit"); names.add("Priya");
        names.add("Zara"); names.add("Alexander");

        System.out.println("\n=== Filter (length > 4) ===");
        filterAndPrint(names, name -> name.length() > 4);

        System.out.println("\n=== Filter (starts with A) ===");
        filterAndPrint(names, name -> name.startsWith("A"));
    }
}
β–Ά Output
=== Calculator === Add: 15 Sub: 5 Mul: 50 Div: 2 === Validator === test@gmail.com valid? true testgmail.com valid? false 9876543210 valid? true 98765 valid? false === Converter === Converted: 1010 Converted: ff === Filter (length > 4) === Passed: Rahul Passed: Priya Passed: Alexander === Filter (starts with A) === Passed: Amit Passed: Alexander
πŸ“‹

Quick Reference

Saari important information ek jagah

πŸ”’ 4 Main Predefined Functional Interfaces

InterfaceAbstract MethodInputOutputUse Case
Predicate<T>test(T t)TbooleanCondition check β€” even, valid, etc.
Function<T,R>apply(T t)TRTransform — String→Integer, etc.
Consumer<T>accept(T t)TvoidPrint, save β€” use karo, return mat
Supplier<T>get()β€”TFactory, random β€” value produce karo
Comparator<T>compare(T o1, T o2)T, TintCustom sort β€” ascending/descending
Runnablerun()β€”voidThread task define karna

⚑ Lambda Syntax Cheat Sheet

// 0 params
() -> System.out.println("Hi");

// 1 param (brackets optional)
x -> x * 2
(x) -> x * 2   // same hai

// 2+ params (brackets must)
(a, b) -> a + b

// Single line = auto return (return mat likho)
(a, b) -> a + b       // returns a+b

// Multi-line = return explicitly likhna ZARURI
(a, b) -> {
    int r = a + b;
    return r;
}
RULE 01 β€” SAM

Exactly 1 abstract method β€” zyada ho to @FunctionalInterface error dega

RULE 02 β€” Annotation

@FunctionalInterface optional hai but likhna chahiye β€” compiler check karta hai

RULE 03 β€” Default/Static OK

default, static, private methods kitne bhi ho sakte β€” abstract count nahi

RULE 04 β€” Object Methods

toString(), equals(), hashCode() β€” Object ke methods hain, count nahi hote

πŸš€ Run karo yahan: OneCompiler.com ya JDoodle.com par copy-paste karke seedha run karo!
🧠

Quiz β€” Test Karo Apni Knowledge

8 questions β€” Functional Interface concepts

Q1. Functional Interface mein kitne abstract methods hote hain?
βœ… Bilkul sahi! SAM = Single Abstract Method β€” exactly 1 hona chahiye.
Q2. @FunctionalInterface annotation ke baare mein kya sach hai?
βœ… Sahi! Optional hai β€” but likhne se compiler check karta hai ki exactly 1 abstract method hai ya nahi.
Q3. Predicate<T> ka abstract method kya return karta hai?
βœ… Correct! boolean test(T t) β€” condition check karta hai, true ya false.
Q4. Multi-line lambda mein return keyword kab likhna padta hai?
βœ… Bilkul! Curly braces = explicit return zaruri. Single line = auto return.
Q5. Consumer<T> ka abstract method kya return karta hai?
βœ… Sahi! void accept(T t) β€” input lo, use karo, return mat karo.
Q6. (a, b) β†’ b - a se sort karne par result kaisa hoga?
βœ… Correct! b - a matlab bade numbers pehle aayenge β€” descending order.
Q7. Ek FI mein default methods ke baare mein kya sach hai?
βœ… Bilkul sahi! Default, static, private β€” sab allowed hain, abstract count nahi hote.
Q8. Supplier<T> ka abstract method signature kya hai?
βœ… Correct! T get() β€” koi input nahi, sirf T type ki value return karta hai.