Java Tutorials
  • Introduction to Java
    • What is Java?
    • History and Features of Java
    • Java Virtual Machine (JVM) and Bytecode
    • Why Java?
  • Setting up Java Development Environment
    • Installing Java Development Kit (JDK)
    • JDK vs JRE
    • Setting up IDE (Eclipse, IntelliJ, NetBeans) or Text Editor (VS Code, Sublime Text)
  • Basic Java
    • First Java Program : Hello World
    • Variable
    • Data Type
    • Constant
    • Date and Format
    • Operator
    • Condition
    • Looping
    • Function
    • Variadic Function
    • Enums
    • Array
    • Collection
    • Exception and Exception Handling
    • Naming Convention
  • Object Oriented Programming (OOP)
    • Classes and Objects
    • Inheritance and Polymorphism
    • Encapsulation and Abstraction
  • File Handling
    • Reading and Writing Binary File
    • Reading and Writing Text File
    • Serialization and Deserialization
  • Multithreading
    • Creating and Running Threads
    • Synchronization
    • Thread Pools and Executors
  • Collections API
    • Sorting and Comparable
    • Searching and Comparator
  • Java Database Connectivity (JDBC)
    • Introduction and Life Cycle
    • Connection to Database (MySQL)
    • Downloading JDBC Drivers for Various Databases
    • Maven and Gradle JDBC Drivers for Various Databases
    • JDBC URL Formats
    • Statement and PreparedStatement
    • CallableStatement
    • Selecting Data using JDBC
    • Inserting Data using JDBC
    • Updating Data using JDBC
    • Deleting Data using JDBC
    • Invoking Function and Stored Procedure using JDBC
  • Lambda
    • Introduction to Lambda Expressions
    • Functional Interface
    • Filtering, Mapping, Reducing
    • Lambda Expressions in Collections
    • Method References
    • Functional Programming Concepts
    • Stream API
    • Error Handling in Lambda Expressions
    • Optional in Functional Programming
    • Parallel Processing with Lambda
    • Functional Programming Patterns
    • Advanced Topics in Lambda Expressions
    • Best Practices and Design Patterns
    • Real-World Use Cases and Examples
Powered by GitBook
On this page
  1. Lambda

Advanced Topics in Lambda Expressions

Lazy Evaluation:

Lazy Evaluation is a programming paradigm where an expression is not evaluated until its value is actually needed. In Java, lazy evaluation is achieved through streams and lambda expressions.

Example of Lazy Evaluation using Streams:

import java.util.List;

public class LazyEvaluationExample {
    public static void main(String[] args) {
        List<Integer> numbers = List.of(1, 2, 3, 4, 5);

        // Lazy evaluation with streams: filter, map, and findFirst are lazily evaluated
        int result = numbers.stream()
            .filter(n -> {
                System.out.println("Filtering: " + n);
                return n % 2 == 0;
            })
            .map(n -> {
                System.out.println("Mapping: " + n);
                return n * 2;
            })
            .findFirst()
            .orElse(0);

        System.out.println("Result: " + result); // Output: Filtering: 1, Filtering: 2, Mapping: 2, Result: 4
    }
}

In this example, filter, map, and findFirst operations are lazily evaluated. They are only executed when the terminal operation (findFirst) is called, and the result is needed.

Infinite Streams:

Infinite Streams are streams that can potentially have an infinite number of elements. They are useful for representing large or infinite datasets.

Example of Infinite Stream:

import java.util.stream.Stream;

public class InfiniteStreamExample {
    public static void main(String[] args) {
        // Generating an infinite stream of natural numbers
        Stream<Integer> naturalNumbers = Stream.iterate(1, n -> n + 1);

        // Using limit to restrict the stream to the first 5 natural numbers
        naturalNumbers.limit(5).forEach(System.out::println); // Output: 1, 2, 3, 4, 5
    }
}

In this example, Stream.iterate(1, n -> n + 1) generates an infinite stream of natural numbers, and limit(5) restricts it to the first 5 numbers.

CompletableFuture and Asynchronous Programming with Lambdas:

CompletableFuture is a class introduced in Java for asynchronous programming. It allows you to perform operations asynchronously and provides a way to compose multiple asynchronous operations using lambda expressions.

Example of CompletableFuture with Lambda:

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

public class CompletableFutureExample {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        // Creating a CompletableFuture for asynchronous execution
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            System.out.println("Performing computation asynchronously");
            return "Result of the computation";
        });

        // Applying a transformation asynchronously using a lambda expression
        CompletableFuture<Integer> transformedFuture = future.thenApplyAsync(result -> {
            System.out.println("Transforming result: " + result);
            return result.length();
        });

        // Getting the result of the transformed computation
        int length = transformedFuture.get();
        System.out.println("Length of the result: " + length); // Output: Length of the result: 25
    }
}

In this example, CompletableFuture.supplyAsync(() -> ...) performs a computation asynchronously. Then, thenApplyAsync applies a transformation to the result of the computation. The entire process happens asynchronously.

Advanced topics in lambda expressions, such as lazy evaluation, infinite streams, and asynchronous programming with CompletableFuture, provide powerful tools for building efficient, responsive, and expressive applications in Java. Understanding these concepts allows developers to design complex systems with ease and efficiency.

PreviousFunctional Programming PatternsNextBest Practices and Design Patterns

Last updated 1 year ago