(loop (blog))

無平不陂 無往不復

Functional Programming in Java

Functional Programming Basics

Functional programming contains the following key concepts:

Pure functional programming has a set of rules to follow too:

Functions as First Class Objects

That means that you can create an "instance" of a function, as have a variable reference that function instance, just like a reference to a String, Map or any other object. Functions can also be passed as parameters to other functions.

In Java, methods are not first class objects. The closest we get is Java Lambda Expressions.

Pure Functions

A function is a pure function if:

Higher Order Functions

A function is a higher order function if at least one of the following conditions are met:

public class HigherOrderFunctionClass {
    public <T> IFactory<T> createFactory(IProducer<T> producer, IConfigurator<T> configurater) {
        return () -> {
            T instance = producer.produce();
            configurater.configurate(instance);
            return instance;
        }
    }
}

Notice that the createFactory() method takes two instances as parameters which are both implementations of interfaces. Java lambda expressions have to implement a functional interface.

No State

By "no state" is typically meant no state external to the function. A function may have local variables containing temporary state internally, but the function cannot reference any member variables of the class or object the function belongs to.

No Side Effects

This means, that a function cannot change any state outside of the function. Changing state outside of a function is referred to as a side effect.

State outside of a function referes both to member variables in the class or object the function, and member variables inside parameters to the function, or state in external systems like file systems or databases.

Immutable Variables

Immutable variables makes it easier to avoid side effects.

Favour Recursion Over Looping

Recursion uses function calls to achieve looping, so the code becomes more functional. Another alternative to loops is the Java Streams API. This API is functionally inspired.

Functional Interfaces

A functional interface is an interface that contains only one abstract method. They can have only one functionality to exhibit.

From Java 8 onwards, lambda expressions can be used to represent the instance of a functional interface. A functional interface can have any number of default methods. As long as the interface only has one method that is not implemented, the interface is considered a functional interface.

Implemention by a Lambda Expression

A Java lambda expression implement a single method from a Java functional interface.

public interface MyFunctionalInterface {
    public void execute();
}

MyFunctionalInterface lambada = () => {
    System.out.println("Executing...");
}

Built-in Functional Interfaces in Java

  1. Function

    The Java Function interface (java.util.function.Function) interface is one of the most central functional interfaces in Java.

    The Function interface represents a function that takes a single parameter and return a single value.

    The Function interface actually contains a few extra methods in addition to the methods listed above, but since they all come with a default implementation, you do not have to implement these extra methods. The only method you have to implement to implement the Function interface is the apply() method.

    You can implement the Function interface in two way.

  2. Predicate

    The Java Predicate interface (java.util.function.Predicate) represents a simple function that takes a single value as parameter, and returns true or false.

    You can implement the Predicate interface using a class or a Java lambda.

  3. UnaryOperator

    The Java UnaryOperator interface represents an operation which takes a single parameter and returns a parameter of the same type.

  4. BinaryOperator

    The Java BinaryOperator represents an operation which takes two parameters and returns a single value. Both parameters and the return type must be of the same type.

  5. Supplier

    The Java Supplier interface represents an function that supplies a value of some sorts. The Supplier interface can also be thought of as a factory interface.

    Here is an example:

  6. Consumer

    The Java Consumer interface represents an function that consumes a value without returning any value. A Java Consumer implementation could be printing out a value, or writing it to a file, or over the network etc.

    Here is an example:

References