Java Functional Interfaces & Lambda

๐Ÿ’ก Java Functional Interfaces & Lambda โ€” Executive Summary

Technical architectural analysis, practical configuration manifests, and deployment instructions for Java Functional Interfaces & Lambda.

Overview

A functional interface is an interface with one abstract method.

Starting from Java8, interfaces can contain default methods with default implementations.

Even if there are multiple default methods, if there is only one abstract method, it is a functional interface.

Lambda expressions in Java can only be used as functional interfaces.

1. Functional Interface

As explained above, a functional interface refers to an interface with only one abstract method.

One abstract method means that there may be multiple default method or static method.

And we use the @FunctionalInterface annotation, which checks whether the interface meets the conditions for a functional interface.

@FunctionalInterface There is no problem in operating and using the functional interface without the annotation, but it is recommended to attach it for interface verification and maintenance.

1.1. Why is it needed?

A functional interface is a general term for an interface in which only one abstract method is defined. The purpose of this interface type is to implement functional programming using Lambda ExpressionVisit Website in Java.

But if you think about it carefully, the form (signature) of the function is diverse. The function may or may not have a return value, and the number of parameters may be one or two. Since there are too many functions to define and use these types of functions individually, Java developers create and provide functional interfaces in advance, which is the functional interface standard API that we will learn in this lesson.

1.2. Functional Interface Example
java
@FunctionalInterface
interface CustomInterface<T> {
// abstract method ์˜ค์ง ํ•˜๋‚˜T myCall();

// default method ๋Š” ์กด์žฌํ•ด๋„ ์ƒ๊ด€์—†์Œdefault void printDefault() {
        System.out.println("Hello Default");
    }

// static method ๋Š” ์กด์žฌํ•ด๋„ ์ƒ๊ด€์—†์Œstatic void printStatic() {
        System.out.println("Hello Static");
    }
}

The above interface is a functional interface.

There is no problem even if you add default method, static method.

If it does not fit the functional interface format anyway, @FunctionalInterface will display the following error.

2. Functional Interfaces provided by Java

functional interface Descriptor Method Method type API usage Parameters Return value
Predicate\ T -> boolean boolean test(T t) boolean test(T t) Determines whether the parameter value meets the conditions and returns a boolean O O
Consumer\ T -> void void accept(T t) void accept(T t) Used as a function that only uses parameters and does not return O X
Supplier\ () -> T T get() T get() Used as a function that does not use parameters and only returns X O
Function\ T -> R R apply(T t) R apply(T t) Mapping (=type conversion) the parameter value and returning it O O
Comparator (T, T) -> int int compare(T o1, T o2)
Runnable () -> void void run() void run() Used in the form of a function that does not use parameters and does not return. Typically used as a thread parameter. X X
Callable () -> T V call()
Operator T -> R R applyAs(T t) Calculating parameters and returning results O O
2.1. Predicate
java
@FunctionalInterface
public interface Predicate<T> {
    boolean test(T t);
}

Predicate takes one argument and returns a boolean type.

In lambda expression, it is expressed as T -> boolean.

2.2. Consumer
java
@FunctionalInterface
public interface Consumer<T> {
    void accept(T t);
}

Consumer takes one argument and returns nothing.

In a lambda expression, it is expressed as T -> void.

Befitting the name consumer, you can think of it as receiving something (a factor) and just consuming it.

2.3. Supplier
java
@FunctionalInterface
public interface Supplier<T> {
    T get();
}

Supplier takes no arguments and returns an object of type T.

In lambda expression, it is expressed as () -> T.

As the name provider suggests, it takes nothing and returns a specific object.

2.4. Function
java
@FunctionalInterface
public interface Function<T, R> {
    R apply(T t);
}

Function takes a T type argument and returns an R type.

In lambda expression, it is expressed as T -> R.

Like a function in a mathematical expression, it takes a specific value and returns a different value.

T and R can also use the same type.

2.5. Comparator
java
@FunctionalInterface
public interface Comparator<T> {
    int compare(T o1, T o2);
}

Comparator takes two T type arguments and returns a int type.

In lambda expression, it is expressed as (T, T) -> int.

2.6. Runnable
java
@FunctionalInterface
public interface Runnable {
    public abstract void run();
}

Runnable does not receive any object and does not return.

In a lambda expression, it is expressed as () -> void.

Runnable As the name suggests, it means โ€œexecutable,โ€ and you can think of it as only executing as the name suggests.

2.7. Callable
java
@FunctionalInterface
public interface Callable<V> {
    V call() throws Exception;
}

Callable takes no arguments and returns a type T object.

In lambda expression, it is expressed as () -> T.

Similar to Runnable, Callable makes more sense when you think of it as โ€œcallable.โ€

Supplier vs Callable

Supplier and Callable are exactly the same.

Returns a specific type without receiving any arguments.

What is the difference between the two?

In fact, you can just think that there is no difference.

Only Callable is a concept that appeared for parallel processing along with Runnable, and functions such as ExecutorService.submit receive Callable as an argument.

3. Bi interface that takes two arguments

For Predicate, Consumer, and Function that receive specific arguments, there is an interface that can receive more than one type.

functional interface Descriptor Method
BiPredicate (T, U) -> boolean boolean test(T t, U u)
BiConsumer (T, U) -> void void accept(T t, U u)
BiFunction (T, U) -> R R apply(T t, U u)

4. Basic specialized interface

The functional interface we have seen so far is called generic functional interface.

All types in Java are reference types or primitive types.

  • Reference Type: Byte, Integer, Object, List
  • Primitive Type: int, double, byte, char

In Consumer , T can only be used as a reference type.

Java provides boxing and unboxing functions to convert basic types and reference types.

  • Boxing: Basic type -> Reference type (int -> Integer)
  • Unboxing: Reference type -> basic type (Integer -> int)

In addition, it provides a function called Autoboxing that automatically converts so that developers can develop without worrying about boxing and unboxing.

For example, in List list, you can use basic types like list.add(3) thanks to autoboxing.

However, because this conversion process costs money, functional interfaces provide a basic-type specialized functional interface to avoid this autoboxing behavior.

If you are sure that only certain types will be accepted, such as IntPredicate, LongPredicate, etc., it is better to use basic specialized interfaces.

In addition to the interfaces introduced below, basic type specialization is also provided for the UnaryOperator and Bi interfaces.

4.1 Predicate (T -> boolean)

After receiving the basic type, return boolean

  • IntPredicate
  • LongPredicate
  • DoublePredicate
4.2. Consumer (T -> void)

Consume after receiving the basic type

  • IntConsumer
  • LongConsumer
  • DoubleConsumer
4.3. Function (T -> R)

Receives a basic type and returns a basic type

  • IntToDoubleFunction
  • IntToLongFunction
  • LongToDoubleFunction
  • LongToIntFunction
  • DoubleToIntFunction
  • DoubleToLongFunction

Receives basic type and returns R type

  • IntFunction
  • LongFunction
  • DoubleFunction

Receives type T and returns basic type

  • ToIntFunction
  • ToDoubleFunction
  • ToLongFunction
4.4. Supplier (() -> T)

Return basic type without receiving anything

  • BooleanSupplier
  • IntSupplier
  • LongSupplier
  • DoubleSupplier

References

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *