Java 8 Functional(SAM) interface:java.util.function package

Introduction to Java Functional(SAM) Interface

Interfaces having exact one abstract method are known as functional interfaces.

Also known as Single Abstract Method Interfaces (SAM Interfaces).

Single abstract method means, default method or abstract method whose implementation is available by default, are allowed.

We will study both the cases with java.util.function package which is newly added .

First of all this is not new concept of Java 8 however, new annotation @FunctionalInterface is added in java 8 features.

Adding @FunctionalInterface annotation enforces that the interface has exact one abstract method. While adding @FunctionalInterface annotation is not mandatory.

If the interface has one abstract method this will be considered as Functional interface in Java 8.
Functional interface annotation enforces the rule of single responsibility. [more about Single responsibility principle]

Usage and Syntax of Java 8 Functional(SAM) Interface

We can write functional interface for general purpose to implement the interface.

However from java 8 functional interfaces are very important, because we use functional interface for implementing Lambada expressions. Lambda is nothing but the shorter way of anonymous implementation of functional interface. If you are new, you can read more about lambda expression.

For writing lambda expression we mostly use function interface. Thanks to java developers, we don’t have to write a new functional interface while writing lambda expressions.

Due to many functional interfaces newly added in java 8. These are very commonly used in lambda expressions or method reference. 

Java.util.function Package contains newly added functional interfaces which are commonly used 

Following are the valid java functional(SAM) interface examples:

public interface MyFunctionalInterface {

public void abstractMethod();


public interface MyFunctionalInterface {

public void abstractMethod();


As the rule suggests, functional interface must have exact one abstract method.

In contrast we can add as many default methods as per our requirements. Because default methods are not abstract. This is the reason whey  some java classes are called as functional interface even if it has many methods.

For example, Java Comparator class is a functional interface having 7 default methods even though it is valid functional interface.

public interface MyFunctionalInterface {

public void abstractMethod();

// Allowed to add default methods

default void print(){

System.out.println(“Default Method 1“);


default void print2(){

System.out.println(“Default Method 2“);



package java.util;

public interface Comparator {

int compare(T var1, T var2);

// Allowed to add default methods

default Comparator reversed() {

return Collections.reverseOrder(this);



Overriding java.lang.Object class method as abstract

Overriding and making a method from java.lang.Object class as abstract in our sam functional interface , also does not count toward the interface’s abstract method. Because any implementing class will always have implementation inherited from java.lang.Object or elsewhere.

@FunctionalInterface                             // valid java 8 SAM interface example
public interface MyFunctionalInterface {

void abstractMethod();

boolean equals(Object obj);         //Because not considered as functional interface abstract method

public String toString();          //Because not considered as functional interface abstract method


For example Java Comparator is a functional interface But, it overrides equals() as abstract method

package java.util;                           //VALID

public interface Comparator {

int compare(T var1, T var2);

boolean equals(Object var1);



Java.util.function Package

As discussed many functional interfaces are added in java 8 java.util.function package. Lets understand more about function package of java 8. This new classes are also known as SAM interfaces.

The SAM interfaces in Java.util.function package are manly categorized into 4 types

  1. Consumer: This interface are having method which takes input, but does not return anything
    Example Consumer<String> print = str -> System.out.println(str);
  2. Supplier : In contrast this interface are having method which returns something without taking any input
    Supplier<Long> useIdSupplier = ()-> userDao.getMaxId()+1;
  3. Predicates : This interface are having method which takes input and returns boolean value
    Predicate<Long> evenChecker = n->n%2==0;
  4. Function : This interface are having method which takes input and returns output
    Function<Long,Long> square = n -> n*n;

Each of the above all 4 categories has provided variety of special interfaces for most common primitive data types. We can use Consumer, Supplier, Predicate or Function Interfaces with wrapper class, however using a specific interface makes code more cleaner and easy. Let’s see the different variants:

  • All of the 4 categories provide special interfaces for int, long and double, However Supplier provides an extra interface for boolean
    • IntConsumer, LongConsumer , DoubleConsumer
    • IntSupplier, LongSupplier, DoubleSupplier, BooleanSupplier
    • IntPredicate, LongPredicate, DoublePredicate
    • IntFunction<R>, LongFunction<R>, DoubleFunction<R>
  • Function provides even more special functions for converting values int, long and double. Name of the classes are self-explanatory
    • ToIntFunction, ToLongFunction, ToDoubleFunction
    • IntToLongFunction, LongToIntFunction
    • IntToDoubleFunction, DoubleToIntFunction
    • LongToDoubleFunction, DoubleToLongFunction
  • Consumer, Predicate and Function have variants that accept 2 input arguments. Supplier doesn’t accept any arguments so it does not have any class of this type
    • BiConsumer<T,U> Accepts two input arguments of type T and U , returns nothing.
    • BiPredicate<T,U> Accepts two input arguments of type T and U , returns boolean value.
    • BiFunction<T,U,R> Accepts two input arguments of type T and U , returns a result of type R.
  • BiConsumer has 3 even more variants which accept one object and other primitive (int long or double)
    • ObjIntConsumer Accepts object of t type and int
    • ObjLongConsumer Accepts object of t type and Long
    • ObjDoubleConsumer Accepts object of t type and Double
  • BiFunction has 3 more variants for accepting 2 arguments and convert to primitive (int long or double)
    • ToIntBiFunction<T,U> Accepts two input arguments of type T and U , returns int result.
    • ToLongBiFunction<T,U> Accepts two input arguments of type T and U , returns Long result.
    • ToDoubleBiFunction<T,U> Accepts two input arguments of type T and U , returns Double.
  • In addition Function provides more types that accept and return object of same type
    • UnaryOperator Accepts single operand that returns a result of same type.
    • IntUnaryOperator Accepts a int value and returns int result.
    • LongUnaryOperator Accepts a Long value and returns int result.
    • DoubleUnaryOperator Accepts a Double value and returns int result.
    • BinaryOperator Accepts two parameter of same type and returns result of same type.
    • IntBinaryOperator Accepts two int value and returns int result.
    • LongBinaryOperator Accepts two Long value and returns Long result
    • DoubleBinaryOperator Accepts two Double value and returns Double result

Fast track reading :

    • Also known as Single Abstract Method interfaces (SAM Interfaces)
    • Exaclty one abstract method  is allowed
    • @FunctionalInterface is optional and it is valid even if annotation would be omitted.
    • Default methods are not abstract so we can add any number of default methods to the functional interface
    • Allows overriding Object class methods as abstract
    • Functional interfaces are very important for writing lambda expression
  • Many functional interfaces are added in java 8 java.util.function package
SummaryAccepts somethingProduces somethingProcess and return true/falseAccepts something and produces something
InputParameter  No InputParameterParameter
Returns  –ResultAlways booleanResult
primitive variantsIntConsumer
For conversion  –  –  –ToIntFunction<T>




For 2 inputsBiConsumer<T,U>  –BiPredicate<T,U>BiFunction<T,U,R>
2 input variantsObjIntConsumer<T>
  –  –ToIntBiFunction<T,U>
Accept and return same type  –  –  –UnaryOperator



Leave a Reply

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