Background
In series of previous posts on Java 8 features we saw Lambda expressions and how to used them.
 We saw basis of a Lambda expression is a functional interface. And then we saw a few functional interfaces as part of introduction to method references -
In this post well see some common functional interfaces that Java provides that you can use at your disposal.
Common Functional interfaces
A new package is introduced since Java 8 that holds all such common functional interfaces. This package is
- java.util.function
 
For now lets go over some commonly used functional interfaces from this package.
NOTE : The convention used here is generic type T for type parameter, for second type parameter the next letter U and for a distinct return type R is used as the generic type.
Predicate : Takes a single paramter of any type and returns a boolean [boolean test(T t)]
Predicate functional interface looks like - 
@FunctionalInterface
public interface Predicate<T> {
    /**
     * Evaluates this predicate on the given argument.
     *
     * @param t the input argument
     * @return {@code true} if the input argument matches the predicate,
     * otherwise {@code false}
     */
    boolean test(T t);
    //other methods
}
It accepts a parameter of type T and returns a boolean.
Note I have skipped other methods in the interface like default and static methods (Remember default methods and static methods do not affect the functional status of an interface)
Eg.
Output :
true
false
Note I have skipped other methods in the interface like default and static methods (Remember default methods and static methods do not affect the functional status of an interface)
Eg.
Predicate<String> emptyPredicate = x -> x.isEmpty();
System.out.println(emptyPredicate.test(""));
System.out.println(emptyPredicate.test("abc"));
Output :
true
false
Consumer : Takes a single paramter of any type and has a void return type [void accept(T t)]
Consumer looks like below -
@FunctionalInterface
public interface Consumer<T> {
    /**
     * Performs this operation on the given argument.
     *
     * @param t the input argument
     */
    void accept(T t);
}
It accepts an input parameter of type T and does does not return anything (has a void return type). It consumes the input.
Eg.
Consumer<String> printFunc = x -> System.out.println(x);
printFunc.accept("Hello World!"); 
Output :
Hello World!
Supplier : Does not take any parameter and returns any type [ T get()]
Supplier looks like -
@FunctionalInterface
public interface Supplier<T> {
    /**
     * Gets a result.
     *
     * @return a result
     */
    T get();
}
 
Eg.
Supplier<String> strSupplier = () -> "SOME_CONSTANT"; System.out.println(strSupplier.get());
Output :
SOME_CONSTANT
I know that a lame example :) You can simple define and use a constant. Have used this to help you understand how it works. All constructor references in method references are essentially variants of supplier.
I know that a lame example :) You can simple define and use a constant. Have used this to help you understand how it works. All constructor references in method references are essentially variants of supplier.
UnaryOperator : Takes a single paramter of any type and returns of same type. [R apply(T t)]
UnaryOperator actually extends Function functional interface. Function looks like below -
public interface Function<T, R> {
    /**
     * Applies this function to the given argument.
     *
     * @param t the function argument
     * @return the function result
     */
    R apply(T t);
}
So as you see it take input parameter of type T and returns a parameter of type R. UnaryOperator is a special kind of Function where T and R are same. So it take input and returns output of same type.
Eg.
UnaryOperator<String> prefixOp = (name) -> "Mr. " + name; 
System.out.println(prefixOp.apply("Aniket"));
Output :
Mr. Aniket
That's some common functional interface. Now there are "Bi" versions of above interfaces that take in 2 inputs. For eg.
- BiConsumer<T, U> : Similar to Consumer<T> but takes two inputs of type T and consumes them i.e void return type.
 - BiPredicate<T, U> : Similar to Predicate<T> but takes 2 inputs of type T and U and returns a boolean.
 - BiFunction<T, U, R> : Similar to Function<T, R> but takes 2 inputs of type T and U and returns a parameter of type R.
 - BinaryOperator<T> : Similar to UnaryOperator<T> but takes 2 parameters of type T and returns parameter of type T.
 
Summary
Related Links
- Using Lambda Expressions from Java 8(OSFG)
 - Using Lambda expressions from Java 8 - Part 2(OSFG)
 - Java 8 Method references and Lambda expression
 - https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html
 - Whats new in Java 8?(OSFG)
 

