Consumer Functional Interface in Java

The Consumer interface is an in-built Functional interface introduced in Java 8, and it is part of the java.util.function package.

It takes a single input, performs some operations, and returns no result.

Since it is a Functional Interface, we can use a Lambda expression to implement it.

Consumer<T> interface

@FunctionalInterface
public interface Consumer<T> {
    /**
     * Performs this operation on the given argument.
     *
     * @param t the input argument
     */
    void accept(T t);

    /**
     * Returns a composed {@code Consumer} that performs, in sequence, this
     * operation followed by the {@code after} operation. If performing either
     * operation throws an exception, it is relayed to the caller of the
     * composed operation.  If performing this operation throws an exception,
     * the {@code after} operation will not be performed.
     *
     * @param after the operation to perform after this operation
     * @return a composed {@code Consumer} that performs in sequence this
     * operation followed by the {@code after} operation
     * @throws NullPointerException if {@code after} is null
     */
    default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (T t) -> { accept(t); after.accept(t); };
    }
}


As you can see, it has a single 
abstract method accept(T t), that takes an input and returns no result.
T in Consumer<T> means it accepts an object of any type.

It also contains one default method andThen() that accepts a Consumer as the input and returns a Consumer.

Implementing the Consumer interface

Example 1:

class Test {

  public static void main(String[] args) {

    Consumer<String> consumer1 = (str) -> {
      System.out.println(str.toUpperCase());
    };
    consumer1.accept("Hello Java 8!");
  }
}
Output: HELLO JAVA 8!
 
Here, inside the braces <>, we specified which type is the input, and we used a Lambda expression to write the implementation of the Consumer interface. 
 
Between the parentheses (), we have the input, and inside the curly braces {}, we wrote a logic that converts the input String to the upper case and prints it.

Example 2:

So far, you have seen the forEach method that we used instead of a for loop.

class Test {

  public static void main(String[] args) {
    List<Integer> numbers = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
    numbers.forEach(number -> System.out.println(number));
  }
}
Output: 1 2 3 4 5

You see that we used the Lambda expression here, and that is because the forEach() method accepts the Consumer interface as an input.

We can also write it like this:

class Test {

  public static void main(String[] args) {
    List<Integer> numbers = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));

    Consumer<Integer> c1 = (number) -> {
      System.out.print(number + " ");
    };

    numbers.forEach(c1);
  }
}
Output: 1 2 3 4 5

Here we assigned a Lambda expression to the variable c1, which is of type Consumer, and we later passed it as a parameter to the forEach method.

Example 3:

In this example, you will see how to use the andThen() method:

First, let’s create a User class:

class User {
  private String name;
  private String username;
  private String membershipType;
  private String address;

  public User(String name, String username, String membershipType, String address) {
    this.name = name;
    this.username = username;
    this.membershipType = membershipType;
    this.address = address;
  }

  public String getName() {
    return name;
  }

  public String getMembershipType() {
    return membershipType;
  }

}


Now let’s write two methods, one for retrieving all users and one for printing users’ names and membership types.

class Test {

  public static void main(String[] args) {
    List<User> users = getAllUsers();
    printNameAndMembershipType(users);
  }

  private static List<User> getAllUsers() {
    List<User> users = new ArrayList<>();

    users.add(new User("John", "john123", "premium", "5th Avenue"));
    users.add(new User("Megan", "meganusr", "gold", "New Light Street"));
    users.add(new User("Steve", "steve1234", "regular", "New Street Avenue"));
    users.add(new User("Melissa", "mell1", "premium", "Ser Kingston Street"));

    return users;
  }

  private static void printNameAndMembershipType(List<User> users) {
    Consumer<User> c1 = (user) -> { System.out.print(user.getName() + ": "); };
    Consumer<User> c2 = (user) -> { System.out.println(user.getMembershipType()); };

    users.forEach(c1.andThen(c2));
    }

}


The output after running the above program is:

Output:
John: premium
Megan: gold
Steve: regular
Melissa: premium


See how we used the andThen() method to chain method calls. That can be very useful in certain situations, especially when working with asynchronous code.

That was all about the Consumer interface in Java. Proceed to the next lesson.

Happy coding!