Functional Interfaces

While Java is primarily an Object-Oriented language, it has powerful functional capabilities. Every “Lambda” expression you write in Java is actually an implementation of a Functional Interface.

1. What is a Functional Interface?

It is an interface that contains exactly one abstract method. You can mark it with @FunctionalInterface to have the compiler enforce this rule.

@FunctionalInterface
public interface Greeter {
    void sayHello(String name);
}

// Using a Lambda to implement it
Greeter g = (name) -> System.out.println("Hello, " + name);

2. Standard Functional Interfaces

You don’t need to create your own interfaces for common tasks. Java provides a set of standard ones in java.util.function:

Interface Method Purpose Example
**Predicate** test(T) Returns boolean. s → s.length() > 5
**Consumer** accept(T) Takes T, returns void. s → System.out.println(s)
Function<T, R> apply(T) Transforms T to R. s &rarr; s.length()
**Supplier** get() Takes nothing, returns T. () &rarr; Math.random()

3. Method References

Sometimes a Lambda just calls an existing method. In those cases, you can use the even-cleaner :: syntax.

// LAMBDA
users.forEach(u -> System.out.println(u));

// METHOD REFERENCE
users.forEach(System.out::println);

Types of Method References:

  1. Static: Math::abs
  2. Instance (Specific Object): myObj::doWork
  3. Instance (Arbitrary Object of Type): String::toLowerCase
  4. Constructor: ArrayList::new

4. Interactive: Lambda Lab

Convert the requirement into a Standard Functional Interface.

Problem: "Check if a number is positive."
Choose the best interface.

5. Default & Static Methods

Functional interfaces can still have multiple methods, as long as only one is abstract. They can have as many default or static methods as they want.

  • This allows interfaces like Predicate to have helper methods like .and(), .or(), and .negate().