Deep Revision Guide β Code + Explanation + Quiz
Core concept samajhte hain β step by step
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.
// 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!
SAM β Exactly 1 abstract method hona chahiye (Single Abstract Method)
@FunctionalInterface annotation optional hai, but best practice hai β compiler check karta hai
default, static, private methods kitne bhi ho sakte hain β abstract count nahi hote
toString(), equals(), hashCode() β Object ke methods count nahi hote
// 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
File: BasicFunctional.java
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"); } }
g2.sayBye())Greet.info())(name) aur name β dono same hainFile: LambdaVariations.java
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")); } }
x ya (x) dono chalega(a, b)File: PredefinedFI.java | Package: java.util.function
| Interface | Method | Input | Output | Use |
|---|---|---|---|---|
| Predicate<T> | test(T t) | T | boolean | Condition check karo |
| Function<T,R> | apply(T t) | T | R | Transform karo |
| Consumer<T> | accept(T t) | T | void | Use karo, return mat karo |
| Supplier<T> | get() | nothing | T | Sirf value do |
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()); } }
File: BuiltinFI.java
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); } }
File: RealWorld.java
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")); } }
Saari important information ek jagah
| Interface | Abstract Method | Input | Output | Use Case |
|---|---|---|---|---|
| Predicate<T> | test(T t) | T | boolean | Condition check β even, valid, etc. |
| Function<T,R> | apply(T t) | T | R | Transform β StringβInteger, etc. |
| Consumer<T> | accept(T t) | T | void | Print, save β use karo, return mat |
| Supplier<T> | get() | β | T | Factory, random β value produce karo |
| Comparator<T> | compare(T o1, T o2) | T, T | int | Custom sort β ascending/descending |
| Runnable | run() | β | void | Thread task define karna |
// 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; }
Exactly 1 abstract method β zyada ho to @FunctionalInterface error dega
@FunctionalInterface optional hai but likhna chahiye β compiler check karta hai
default, static, private methods kitne bhi ho sakte β abstract count nahi
toString(), equals(), hashCode() β Object ke methods hain, count nahi hote
8 questions β Functional Interface concepts
@FunctionalInterface annotation ke baare mein kya sach hai?Predicate<T> ka abstract method kya return karta hai?boolean test(T t) β condition check karta hai, true ya false.Consumer<T> ka abstract method kya return karta hai?void accept(T t) β input lo, use karo, return mat karo.(a, b) β b - a se sort karne par result kaisa hoga?Supplier<T> ka abstract method signature kya hai?T get() β koi input nahi, sirf T type ki value return karta hai.