Supplier, Consumer and BiConsumer in Java 8

Introduction

I will discuss here about the new feature added to Java 8 – a functional interface, Supplier, Consumer and BiConsumer. In simple words, a supplier is a method that returns a value. A supplier is any method which takes no arguments and returns a value. Its job is to supply an instance of an expected class.

Whereas, a consumer is a method that consumes some value (as in method argument), and does some operations on them. So a Consumer is any method which takes arguments and returns nothing.

A consumer is invoked for its side-effects. In Java terms, a Consumer is an idiom for a void method. ‘setter’ methods are good examples of consumers.

A BiConsumer is similar to the consumer and it accepts two inputs and does not return anything.

Prerequisites

Java at least 8

Supplier

For example, every reference to a getter method is a supplier.

public class MyClass {
	private Integer count;

	public Integer getCount() {
		return this.count;
	}
}

Its instance method reference myClass::getCount is an instance of Supplier.

Supplier is a functional interface, in Java 8 under package java.util.function, that represents the structure and does not take any input but returns an output. This functional interface can be used as the assignment target for a lambda expression or method reference. It’s written in the following manner – Java source documentation:

@FunctionalInterface
public interface Supplier<T> {

  T get();

}

The purpose of this in-built functional interface, Supplier, is to provide a ready-made template for functional interface having common function descriptor (functional method signature/definition).

The functional interfaces defined under package java.util.function do not have semantics and they merely represent the structure of a function that returns a value or takes number of arguments.

The Supplier interface also have a method T get() that returns a value of of type T.

A supplier is a way to create instance of a method that returns something or in other words its job is literally to supply an instance of an expected class.

Supplier functional interface doesn’t take any input but returns an output. Therefore whenever you need a function that returns something, for example, an Integer, but takes no output, this is an instance of Supplier.

Examples for Supplier functional interface using lambda expression can be given as shown below:

Supplier<Integer> supplierInteger = () -> 50;
System.out.println(supplierInteger.get());

Supplier<String> supplierString = () -> "Soumitra";
System.out.println(supplierString.get());

You can have a look at examples on how to use supplier:

Consumer

For example, every reference to a setter method is consumer:

public class MyClass {
	private Integer count;

	public void setCount(Integer count){
		this.count = count;
	}
}

Its instance method reference myClass::setCount is an instance of consumer.

So, if you want to input an Integer and do something with it with no output, then instead of defining your own interface use an instance of Consumer.

Consumer functional interface in Java 8 under package java.util.function represents the structure and takes input but does not return any output. This functional interface can be used as the assignment target for a lambda expression or method reference. It’s written in the following manner – Java source documentation:

@FunctionalInterface
public interface Consumer<T> {

  void accept(T t);

  default Consumer<T> andThen(Consumer<? super T> after);

}

Represents an operation that accepts a single input argument and returns no result. Unlike most other functional interfaces, Consumer is expected to operate via side-effects. This is a functional interface whose functional method is accept(Object).

The default method returns a composed Consumer that performs, in sequence, this operation followed by the 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 after operation will not be performed.

Example of side effect in the Consumer:

User user = new User("Soumitra");
Consumer<User> updateName = u -> u.setName("Roytuts");
updateName.accept(user);

System.out.println(user.getName()); //Roytuts

In the above code snippets, notice that the name of the user has been changed later. This is a side effect of the Consumer functional interface.

BiConsumer

BiConsumer is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference. It represents an operation that accepts two input arguments and returns no result. This is the two-arity specialization of Consumer. Unlike most other functional interfaces, BiConsumer is expected to operate via side-effects.

This is a functional interface whose functional method is accept(Object, Object).

@FunctionalInterface
public interface BiConsumer<T, U> {

  void accept(T t, U u);

  default BiConsumer<T,U>	andThen(BiConsumer<? super T,? super U> after)

}

Type Parameters:

T – the type of the first argument to the operation
U – the type of the second argument to the operation

Example of BiConsumer can be given as:

BiConsumer<String, String> bc = (x, y) -> {
	System.out.println(x + y);
};

bc.accept("1", "2");

The example using method reference can be given as:

BiConsumer<User, String> urbc = BiConsumerExample::showDetails;
urbc.accept(new User("Liton"), "32");

You can download the whole source code later from the Source Code section.

Examples – Supplier, Consumer and BiConsumer

Supplier

In this example, the Supplier is supplying string value.

package com.roytuts.java.supplier.consumer;

import java.util.function.Supplier;

public class SupplierExample {

	public static void main(String[] args) {
		supply(() -> "Hi");
		supply(() -> "Hey");
		supply(() -> "Hello");
		
		Supplier<Integer> supplierInteger = () -> 50;
		System.out.println(supplierInteger.get());
		
		Supplier<String> supplierString = () -> "Soumitra";
		System.out.println(supplierString.get());
	}

	public static void supply(Supplier<?> supplier) {
		System.out.println(supplier.get());
	}

}

Running the above program you will see the following output:

Hi
Hey
Hello
50
Soumitra

Consumer

The Consumer consumes string value in the following example.

package com.roytuts.java.supplier.consumer;

import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;

public class ConsumerExample {

	public static void main(String[] args) {
		List<String> greets = Arrays.asList("Hi", "Hey", "Hello");

		Consumer<String> consumer = new Consumer<String>() {
			@Override
			public void accept(String s) {
				System.out.println(s);
			}
		};

		greets.forEach(consumer);

		System.out.println("===============================");


		User user = new User("Soumitra");
		Consumer<User> updateName = u -> u.setName("Roytuts");
		updateName.accept(user);

		System.out.println(user.getName());
	}

}

Executing the above program will give you the following output:

Hi
Hey
Hello
===============================
Roytuts

BiConsumer

Using lambda and method reference the example for BiConsumer functional interface can be written as:

package com.roytuts.java.supplier.consumer;

import java.util.function.BiConsumer;

public class BiConsumerExample {

	public static void main(String[] args) {
		BiConsumer<String, String> bc = (x, y) -> {
			System.out.println(x + y);
		};

		bc.accept("1", "2");

		System.out.println("=========================");

		// Using lambda expression
		BiConsumer<User, String> ubc = (user, age) -> {
			System.out.println(user.getName() + " -> " + age);
		};

		ubc.accept(new User("Rahul"), "35");

		// Using method reference
		BiConsumer<User, String> urbc = BiConsumerExample::showDetails;
		urbc.accept(new User("Liton"), "32");
	}

	private static void showDetails(User user, String age) {
		System.out.println(user.getName() + " -> " + age);
	}

}

Running the above program will give you the following output:

12
=========================
Rahul -> 35
Liton -> 32

That’s all about Supplier, Consumer and BiConsumer examples.

Source Code

Download

Author: Soumitra

Hi, I am, Soumitra, the owner of roytuts.com and it is my passion for sharing my knowledge and I have been writing blogs on various technologies since 2014. If you like my tutorials, you may also want to like my Facebook Page, follow me on Twitter, Github.

Leave a Reply

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