Java Tutorial

Operators

Flow Control

String

Number and Date

Built-in Classes

Array

Class and Object

Inheritance and Polymorphism

Exception Handling

Collections, Generics and Enumerations

Reflection

Input/Output Stream

Annotation

Use Java Lambda Expressions

In this tutorial, you will learn how to use lambda expressions in Java to simplify your code when working with functional interfaces.

  • Functional Interfaces:

A functional interface is an interface with a single abstract method. Lambda expressions can be used to represent an instance of a functional interface. Java provides a set of built-in functional interfaces in the java.util.function package, such as Function, Predicate, Consumer, and Supplier.

  • Lambda Expression Syntax:

Lambda expressions have the following syntax:

(parameters) -> { body }
  • parameters: A comma-separated list of parameters, enclosed in parentheses. For a single parameter, parentheses can be omitted.
  • arrow: The arrow (->) separates the parameters from the body.
  • body: The lambda expression body, which can be a single expression or a block of code enclosed in curly braces.
  • Using Lambda Expressions:

Here's an example of using a lambda expression with the Predicate functional interface to filter a list of integers:

import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;

public class LambdaExample {
    public static void main(String[] args) {
        List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

        Predicate<Integer> isEven = n -> n % 2 == 0;
        List<Integer> evenNumbers = filter(numbers, isEven);

        System.out.println("Even numbers: " + evenNumbers);
    }

    private static <T> List<T> filter(List<T> list, Predicate<T> predicate) {
        List<T> filtered = new ArrayList<>();
        for (T item : list) {
            if (predicate.test(item)) {
                filtered.add(item);
            }
        }
        return filtered;
    }
}

In this example, we define a lambda expression isEven that implements the Predicate functional interface. The filter method accepts a list and a predicate, and returns a new list containing the elements that satisfy the predicate. When we pass the isEven lambda expression to the filter method, it filters the even numbers from the input list.

  • Method References:

If your lambda expression calls an existing method without modifying the input parameters, you can use a method reference instead. The syntax for method references is ClassName::methodName or object::methodName.

Here's an example of using a method reference with the Consumer functional interface to print a list of strings:

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

public class MethodReferenceExample {
    public static void main(String[] args) {
        List<String> names = List.of("Alice", "Bob", "Charlie", "David");

        Consumer<String> printer = System.out::println;
        names.forEach(printer);
    }
}

In this example, we use the method reference System.out::println to create a Consumer that prints the input string. We then use the forEach method of the List interface to apply the printer consumer to each element in the list.

In conclusion, lambda expressions in Java provide a concise way to represent instances of functional interfaces and simplify the code when working with functional programming concepts. They are particularly useful with Java's built-in functional interfaces and collection methods, like filtering, mapping, and reducing.

  1. Lambda expressions vs anonymous classes in Java: Lambda expressions provide a concise way to represent anonymous functions, often replacing verbose anonymous classes.

    // Anonymous class
    Runnable runnable1 = new Runnable() {
        @Override
        public void run() {
            System.out.println("Anonymous class");
        }
    };
    
    // Lambda expression
    Runnable runnable2 = () -> System.out.println("Lambda expression");
    
  2. Using lambda expressions for functional programming in Java: Lambda expressions enable functional programming paradigms in Java, allowing the use of functions as first-class citizens.

    // Functional interface
    interface MyFunction {
        void apply();
    }
    
    // Using lambda expression for functional programming
    MyFunction myFunction = () -> System.out.println("Functional programming in Java");
    
  3. Functional interfaces and lambda expressions in Java: Functional interfaces have a single abstract method, making them suitable for lambda expressions.

    // Functional interface
    interface MyFunction {
        void apply();
    }
    
    // Using lambda expression with functional interface
    MyFunction myFunction = () -> System.out.println("Lambda with functional interface");
    
  4. Lambda expressions for collections in Java: Lambda expressions simplify collection processing, such as iterating over elements.

    List<String> strings = Arrays.asList("Java", "is", "fun");
    
    // Using lambda expression for iteration
    strings.forEach(str -> System.out.println(str));
    
  5. Filtering and mapping with lambda expressions in Java: Lambda expressions are powerful for filtering and mapping elements in collections.

    List<String> strings = Arrays.asList("Java", "is", "fun");
    
    // Using lambda expression for filtering and mapping
    strings.stream()
           .filter(str -> str.length() > 2)
           .map(String::toUpperCase)
           .forEach(System.out::println);
    
  6. Java streams and lambda expressions: Streams in Java leverage lambda expressions for concise and expressive data processing.

    List<String> strings = Arrays.asList("Java", "is", "fun");
    
    // Using streams and lambda expressions
    long count = strings.stream()
                       .filter(str -> str.length() > 2)
                       .count();
    
    System.out.println("Count: " + count);
    
  7. Parallel processing with lambda expressions in Java: Lambda expressions can be used with parallel streams to achieve parallel processing.

    List<String> strings = Arrays.asList("Java", "is", "fun");
    
    // Using parallel streams and lambda expressions
    strings.parallelStream()
           .forEach(System.out::println);
    
  8. Handling exceptions with lambda expressions in Java: Lambda expressions can handle exceptions using try-catch blocks.

    // Lambda expression with exception handling
    Runnable runnable = () -> {
        try {
            // Code that may throw an exception
        } catch (Exception e) {
            // Handling the exception
        }
    };
    
  9. Method references and lambda expressions in Java: Method references provide a shorthand syntax for lambda expressions when calling an existing method.

    List<String> strings = Arrays.asList("Java", "is", "fun");
    
    // Using lambda expression
    strings.forEach(str -> System.out.println(str));
    
    // Using method reference
    strings.forEach(System.out::println);
    
  10. Lambda expressions for concurrency in Java: Lambda expressions can be used in conjunction with Java's concurrency features, such as ExecutorService.

    ExecutorService executorService = Executors.newFixedThreadPool(5);
    
    // Using lambda expression for concurrent task
    executorService.submit(() -> System.out.println("Concurrent task"));
    
    executorService.shutdown();