Skip to main content

Functional interfaces in Java 8

· 3 min read

A functional interface is an interface that specifies exactly one abstract method. in Java8 interfaces can now also have default methods (that is, a method with a body that provides some default implementation for a method in case it isn’t implemented by a class). An interface is still a functional interface if it has many default methods as long as it specifies only one abstract method.

Some interfaces that we can consider as functional interfaces are:

public interface Comparator<T> { 
int compare(T o1, T o2);
}

public interface FileFilter {
boolean accept(File x);
}

public interface ActionListener {
void actionPerformed(...);
}

public interface Callable<T> {
T call();
}

public interface Runnable {
void run();
}

Lambda expressions let you provide the implementation of the abstract method of a functional interface directly inline and treat the whole expression as an instance of a functional interface, that is, as an instance of a concrete implementation of the functional interface. For example, the following codes are equivalents:

Runnable r = () -> System.out.println("Hello World");

equivalent to

Runnable r = new Runnable() {
public void run() {
System.out.println("Hello World");
}
}

We can use @FuntionalInterface as an informative annotation type to indicate that an interface type declaration is intended to be a functional interface. Compilers are required to generate an error message if the annotated interface does not satisfy the requirements of a functional interface. However, the compiler will treat any interface meeting the definition of a functional interface as a functional interface regardless of whether or not a FunctionalInterface annotation is present on the interface declaration.

Some of the most important functional interfaces in Java 8, that you can find them in java.util.function package, are:

Interface nameArgumentsReturnsExample
ConsumerTvoidString s -> System.out.println(s)
BiConsumer<T, U>T, Uvoid(k, v) -> System.out.println("key:" + k + ", value:"+ v)
SupplierNoneT() -> createLogMessage()
Function<T, R>TRStudent s -> s.getName()
BiFunction<T,U,R>T, UR(String name, Student s) -> new Teacher(name, student)
UnitaryOperatorTTString s -> s.toLowerCase()
BinaryOperatorT, TT(String x, String y)-> {
  if (x.length() > y.length()) return x;
 return y;
}
PredicateTbooleanStudent s -> s.graduationYear() == 2011

Related posts:

Lambda expressions in Java 8