How to use Java's functional Consumer interface example

Quite often a Java Stream or other component needs an object passed to it in order to perform some type of calculation or process, but when the process is complete, nothing gets returned from the method. This is where Java’s functional Consumer interface comes in handy.

According to the JavaDoc, the Consumer interface accepts any type of object as input. The java.util.function.Consumer class has one non-default method named accept which takes a single object as its argument and has a void return type.

java.util.function.Consumer<T>
Consumer function type Parameters:
T - object type to be passed to the Consumer accept method

Consumer function methods:
void accept(T t)  This method operates on a single object passed in as an argument.
default Consumer<T> andThen(Consumer after)  Returns a functional Consumer interface 
that can be daisy chained in sequence.

The Consumer's non-default accept method takes a single argument and does not return a result.

Functional programming with a Java Consumer

Sometimes programmers new to lambdas and streams get intimidated by the components defined in the java.util.function package, so I always like to remind developers that all of the interfaced defined in this package follow all of the standard, pre Java 8 rules for implementing interfaces. As such, you can incorporate the functional Consumer interface into your code simply by creating a class that implements java.util.function.Consumer, or by coding an inner class.

Consumer example tutorial

Here is the Java code used in this Consumer function example tutorial.

Implement a Consumer with a Java class

Here is the Java Consumer function implemented using a Java class instead of a lambda expression:

class SimpleConsumerExample implements Consumer<Long> {
  public void accept(Long t) {
    System.out.println(t*t);
  }
}

Inside of a main method or any other piece of Java code, the SimpleConsumerExample class can be instatiated according to traditional Java syntax rules:

/* Java Consumer example using a class */
SimpleConsumerExample sce = new SimpleConsumerExample();
sce.accept(new Long(2));

Similarly, an inner class can also be used:

/* Functional Consumer example using inner class */
Consumer<Long> innerConsumer = new Consumer<Long>() {

  @Override
  public void accept(Long t) {
    System.out.println(t*t);
  }
};

innerConsumer.accept(new Long(4));

Lambda and Consumer interface example

As you can see, there is nothing special about the interfaces defined in the java.util.function package. They are regular Java interfaces that comply with all of the traditional rules of syntax. However, they also work with lambda expressions, which is where functional interfaces really shine. Here is the functional Consumer interface example implemented using a somewhat verbose lambda expression:

Consumer<Long> lambdaConsumer = (Long t) -> System.out.println(t*t);
lambdaConsumer.accept(new Long(5));

I like to use a verbose lambda syntax when demonstrating how they work, but one of the reasons for using lambda expressions is to make Java less verbose. So the lambda expression above can be written in a much more concise manner:

Consumer<Long> conciseLambda = t -> System.out.println(t*t);
conciseLambda.accept(new Long(10));

Sample Consumer interface use cases

The functional Consumer interface is used extensively across the Java API, with a number of classes in the java.util.function package, such as ObjIntConsumer, BIConsumer and IntConsumer providing extended support to the basic interface.

Furthermore, a variety of methods in the Java Stream API take the functional Consumer interface as an argument, inclusing methods such as collect, forEach and peek.

There are only a few key intefaces you need to master in order to become a competent functional programmer. If you understand the concepts laid out in this functional Consumer interface example, you’re well on your way to mastering the update Java APIs.

Consumer tutorial code

Here is the code used in this tutorial on how to use the Consumer.

package com.mcnz.lambda;
import java.util.function.*;

public class JavaConsumerExample {

  public static void main (String args[]) {

    /* Java Consumer example using a class */
    SimpleConsumerExample sce = new SimpleConsumerExample();
    sce.accept(new Long(2));

    /* Functional Consumer example using inner class */
    Consumer<Long> innerConsumer = new Consumer<Long>() {
      @Override
      public void accept(Long t) {
        System.out.println(t*t);
      }
    };
    innerConsumer.accept(new Long(4));

    /* Implemented Consumer function with verbose lambda expression */
    Consumer<Long> lambdaConsumer = (Long t) -> System.out.println(t*t);
    lambdaConsumer.accept(new Long(5));

    /* Concise lambda and Consumer function example */
    Consumer<Long> conciseLambda = t -> System.out.println(t*t);
    conciseLambda.accept(new Long(5));

  }
}

/* Class implementing functional Consumer example */
class SimpleConsumerExample implements Consumer<Long> {
  public void accept(Long t) {
    System.out.println(t*t);
  }
}