Functional Interfaces in Java 8

With Java 8, the concept of Lambdas was finally added to the language specification. Often you’re using Lambdas on the fly without assigning them to a variable.

List<String> names = Arrays.asList("Arthur", "Marvin", "Zaphod");
names.stream().forEach(name -> System.out.println(name));

However if you want to save a Lambda into a variable and pass it as a method parameter or use it later, you need to pick the applicable type.

public static void main(String[] args) {
  List<String> names = Arrays.asList("Arthur", "Marvin", "Zaphod");
  Consumer<String> print = name -> System.out.println(name);
  applyToAllNames(names, print);
}

private static void applyToAllNames(List<String> names, Consumer<String> print) {
  names.stream().forEach(print);
}

Here is the list of the Interfaces you might use from the Java API:

  • Runnable // nothing
  • Supplier<T> // a return value
  • Consumer<T> // a parameter
  • BiConsumer<T, U> // two parameters
  • Function<T, R> // a parameter and a return value
  • BiFunction<T, U, R> // two parameters and a return value
  • UnaryOperator<T> // the parameter and the return value have the same type
  • BinaryOperator<T> // two parameters and a return value of the same type
  • Predicate<T> // a parameter and a boolean return value
  • BiPredicate<T, U> // two parameters and a boolean return value

InformIT presents all those Interfaces using a nice table in the article “Java SE 8 for the Really Impatient: Programming with Lambdas“.