Consumer Interface in Java 8

Definition

Consumer Interface is a functional interface introduced in Java 8. It is a part of the java.util.function.Consumer package. It takes in one argument and produces a result however it does not return any value.


Methods

The consumer interface is having an abstract method accept() and a default method andThen ().

accept method

It is an abstract method that takes an argument of type T and executes a set of statements. accept method does not return any value.

Syntax : void accept(T t) ;

We will try to replicate Consumer Interface from the java source code in our below example :

interface Consumer<T> {
   void accept(T t);
}

class ConsumerImpl implements Consumer<Integer> {
   @Override
   public void accept(Integer t) {
      System.out.println("Value is doubled : "+ 2 * t);	
   }
}

public class ConsumerInterfaceDemo {
   public static void main(String[] args) {
      Consumer<Integer> consumer1 = new ConsumerImpl();
      consumer1.accept(10);
   }
}

O/P : Value is doubled : 20

We can clean up the above code base further. As a Consumer is a functional interface hence Instead of writing an Implementor class we can use the lambda expression directly. In Short, we can depict the method of a functional interface as a lambda expression.

interface Consumer&lt;T&gt; {
   void accept(T t);
}

public class ConsumerInterfaceDemo {
   public static void main(String[] args) {
      Consumer<Integer> consumer = (Integer t) -> { 
         System.out.println("Value is doubled : "+ 2 * t);	
      };
      consumer.accept(20);
   }
}
O/P : Value is doubled : 40

We can pass the above lambda expression as an argument to some other method as well. You might have heard about forEach method. Let us check below a very common example that we come across many a time.

import java.util.ArrayList;
import java.util.List;

public class ConsumerInterfaceDemo {
   public static void main(String[] args) {
      List<Integer> list =  new ArrayList<>();
      list.add(10);
      list.add(15);
      list.add(20);
      list.forEach((Integer t) -> System.out.println("Value is doubled : "+ 2 * t));
   }
}

O/P : Value is doubled : 20
Value is doubled : 30
Value is doubled : 40

forEach method accepts the java.util.function.Consumer as an argument. To demonstrate check the snap and code below :

consumer interface in java
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

public class ConsumerInterfaceDemo {
   public static void main(String[] args) {
      List<Integer> list =  new ArrayList<>();
      list.add(10);
      list.add(15);
      list.add(20);

      Consumer<Integer> consumer = (Integer t) -> System.out.println("Value is doubled : "+ 2 * t);

      list.forEach(consumer);
   }
}

O/P : Value is doubled : 20
Value is doubled : 30
Value is doubled : 40

forEach() calls the accept() method internally . Below is a snap from iterable.class

consumer interface

andThen method

It is a Default method that accepts a Consumer as an argument and returns back a composed Consumer. Consumer object calls the “andThen()” method.

Syntax : default Consumer andThen(Consumer after);

Suppose there are 2 Consumers Consumer1 and Consumer2. As we know Consumer object calls the “andThen()” method hence the calling approach will be :

Consumer1.andThen(Consumer2) .

Here Consumer1 will execute first and then Consumer2. I hope you understand why the method name is “andThen”. To summarize let us try to understand it better with an example :

import java.util.function.Consumer;

class Student {
  int rollNumber;
  String name;

  public int getRollNumber() {
    return rollNumber;
  }
  public void setRollNumber(int rollNumber) {
    this.rollNumber = rollNumber;
  }
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }

  @Override
  public String toString() {
    return "Student [rollNumber=" + rollNumber + ", name=" + name + "]";
  }
}

public class ConsumerInterfaceDemo {
  public static void main(String[] args) {
    Consumer<Student> consumer1 = (Student student) -> {
      student.setName("Suraj");
      student.setRollNumber(101);
    };

    Consumer<Student> consumer2 = (Student student) ->                        System.out.println(student);

    Consumer<Student> resultConsumer = consumer1.andThen(consumer2);
    resultConsumer.accept(new Student());
  }
}

O/P : Student [rollNumber=101, name=Suraj]

What happens if the second consumer is null?

A null pointer exception is thrown.

import java.util.function.Consumer;

class Student {
  int rollNumber;
  String name;

  public int getRollNumber() {
    return rollNumber;
  }
  public void setRollNumber(int rollNumber) {
    this.rollNumber = rollNumber;
  }
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }

  @Override
  public String toString() {
    return "Student [rollNumber=" + rollNumber + ", name=" + name + "]";
  }
}

public class ConsumerInterfaceDemo {

  public static void main(String[] args) {

    Consumer<Student> consumer1 = (Student student) -> {
      student.setName("Suraj");
      student.setRollNumber(101);
    };

    Consumer<Student> resultConsumer = consumer1.andThen(null);
    resultConsumer.accept(new Student());
  }
}

O/P : Exception in thread “main” java.lang.NullPointerException
at java.util.Objects.requireNonNull(Objects.java)
at java.util.function.Consumer.andThen(Consumer.java)
at fifth.ConsumerInterfaceDemo.main(ConsumerInterfaceDemo.java)


What happens if both Consumers throw some runtime exception?

The Execution should stop immediately after executing the first Consumer. Once the exception is thrown the next steps won’t be executed. To summarize let us try to understand it better with an example :

import java.util.function.Consumer;

class Student {
  int rollNumber;
  String name;

  public int getRollNumber() {
    return rollNumber;
  }
  public void setRollNumber(int rollNumber) {
    this.rollNumber = rollNumber;
  }
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }

  @Override
  public String toString() {
    return "Student [rollNumber=" + rollNumber + ", name=" + name + "]";
  }
}

public class ConsumerInterfaceDemo {

  public static void main(String[] args) {

    Consumer<Student> consumer1 = (Student student) -> {
      student.setName("Suraj");
      student.setRollNumber(101);
      throw new RuntimeException("Exception from Consumer1");
    };

    Consumer<Student> consumer2 = (Student student) -> {
      System.out.println(student);
      throw new RuntimeException("Exception from Consumer2");
    };

    try {
      consumer1.andThen(consumer2).accept(new Student());
    } catch (Exception e) {

      System.out.println(e.getMessage());
    }
  }
}

O/P : Exception from Consumer1

What happens if the second Consumer throws a runtime exception?

The first Consumer executes properly.

import java.util.function.Consumer;

class Student {

  int rollNumber;
  String name;

  public int getRollNumber() {
    return rollNumber;
  }
  public void setRollNumber(int rollNumber) {
    this.rollNumber = rollNumber;
  }
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }

  @Override
  public String toString() {
    return "Student [rollNumber=" + rollNumber + ", name=" + name + "]";
  }
}

public class ConsumerInterfaceDemo {

  public static void main(String[] args) {

    Consumer<Student> consumer1 = (Student student) -> {
      student.setName("Suraj");
      student.setRollNumber(101);
    };

    Consumer<Student> consumer2 = (Student student) -> {
      System.out.println(student);
      throw new RuntimeException("Exception from Consumer2");
    };

    try {
      consumer1.andThen(consumer2).accept(new Student());
    } catch (Exception e) {

      System.out.println(e.getMessage());
    }
  }
}

O/P : Student [rollNumber=101, name=Suraj]
Exception from Consumer2

I hope you found this article interesting and valuable. In this article, we have covered what is a consumer interface in java and its methods with proper examples. Please share this article with your friends and help me grow. If you are having any concerns or questions about this article please comment below. If you want to get in touch with me please visit the Contact Me page and send an email.

Leave a Comment