Java > Java 8 Features > Lambda Expressions > Using Built-in Functional Interfaces

Lambda Expressions with Built-in Functional Interfaces: Example 1 - Predicate

This snippet demonstrates how to use a lambda expression with the `Predicate` functional interface, a built-in interface in Java. `Predicate` is a functional interface that represents a boolean-valued function of one argument. It's commonly used to filter collections.

Code Example

This code showcases how to use the `Predicate` functional interface with lambda expressions to filter a list of strings. The `startsWithA` predicate filters strings that begin with 'A', and the `lengthGreaterThan4` predicate filters strings whose length exceeds 4. The `filter` method of the `Stream` API accepts a `Predicate` and returns a new stream containing elements that satisfy the predicate.

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

public class PredicateExample {

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

        // Using Predicate to filter names starting with 'A'
        Predicate<String> startsWithA = name -> name.startsWith("A");

        List<String> namesStartingWithA = names.stream()
                .filter(startsWithA)
                .collect(Collectors.toList());

        System.out.println("Names starting with A: " + namesStartingWithA); // Output: [Alice, Anna]

        // Using Predicate to filter names with length greater than 4
        Predicate<String> lengthGreaterThan4 = name -> name.length() > 4;

        List<String> namesLongerThan4 = names.stream()
                .filter(lengthGreaterThan4)
                .collect(Collectors.toList());

        System.out.println("Names longer than 4 characters: " + namesLongerThan4); // Output: [Alice, Charlie, David]

    }
}

Concepts Behind the Snippet

This snippet utilizes the `Predicate` functional interface. A functional interface is an interface with a single abstract method. The `Predicate` interface has the `test(T t)` method, which accepts an argument of type `T` and returns a boolean. Lambda expressions provide a concise way to implement the abstract method of a functional interface.

Real-Life Use Case

Imagine you have a large dataset of customer records. You can use `Predicate` with lambda expressions to filter customers based on specific criteria, such as age, location, purchase history, or subscription status. This allows you to efficiently extract relevant data for targeted marketing campaigns or data analysis.

Best Practices

  • Keep lambda expressions short and focused on a single task.
  • Use meaningful variable names for lambda expression parameters.
  • Avoid side effects within lambda expressions, particularly when used with streams.
  • Use method references (e.g., `String::toUpperCase`) when applicable for improved readability.

Interview Tip

Be prepared to explain the concept of functional interfaces and lambda expressions. Be able to describe how they enable functional programming paradigms in Java. Also, understand different built-in functional interfaces such as `Predicate`, `Function`, `Consumer`, and `Supplier` and their use cases. Practice writing simple lambda expressions to demonstrate your proficiency.

When to Use Them

Use `Predicate` when you need to evaluate a condition and return a boolean value. This is particularly useful for filtering collections, validating input, or implementing complex business rules. Use lambda expressions when you want to pass behavior as an argument to a method.

Alternatives

Prior to Java 8, you would typically use anonymous inner classes to achieve similar functionality. However, lambda expressions offer a more concise and readable syntax. Traditional `for` loops could also be used for filtering, but streams and lambda expressions generally offer better performance and readability, especially for complex operations.

Pros

  • Conciseness: Lambda expressions provide a more compact syntax compared to anonymous inner classes.
  • Readability: They often lead to more readable and maintainable code.
  • Functional Programming: They enable functional programming paradigms in Java.
  • Parallelization: They facilitate parallel processing with streams.

Cons

  • Debugging: Debugging can be more challenging compared to traditional methods.
  • Complexity: Overuse or poorly written lambda expressions can reduce code readability.
  • Learning Curve: Developers new to functional programming may face a learning curve.

FAQ

  • What is a functional interface?

    A functional interface is an interface with a single abstract method. It can have multiple default or static methods. It can be annotated with `@FunctionalInterface`.
  • What is a lambda expression?

    A lambda expression is a concise way to represent an anonymous function. It can be used to implement the abstract method of a functional interface.
  • What is the purpose of the `Predicate` interface?

    The `Predicate` interface represents a boolean-valued function of one argument. It is commonly used for filtering collections.