Consumer interface in Java
The Consumer
interface was introduced in Java 1.8. Below is a an excerpt from the official documentation
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.
I want to talk about the Consumer
functional interface in this article because I find it very useful and use it often.
Consumer definition
Consumer
is an interface with as single abstract method accept(T t)
.
interface Consumer<T> {
public void accept(T t);
}
The accept
method, as its name suggests, "consumes" a value and performs a specific operation on it.
Uses of Consumer interface
- The behavior (accept method) of the consumer interface is well known. As a result, it increases the readability of the code.
- Enhances code reusability by leveraging pre-existing interfaces rather than creating custom ones for the same behavior.
- As it is a functional interface, it can be efficiently defined using lambda expressions.
- The
Consumer
interface is commonly utilized in many new Java methods, such as those found in theStream
class. - The
Consumer
instances can be executed sequentially by utilizing theandThen
method.
Example of Consumer interface
Let us view some examples of Consumer
interface. To gauge its usability, we will first try to solve the problem without Consumer
interface.
Problem Statement
Let us consider a class PerformLongOperation
which is doing some complex operation and keeps posting progress of its update to the listener. The listener needs to be passed as a parameter of doTask
function which perform the actual task.
Solution 1: Using interface
Here, we will use IOnTaskUpdateCallback
interface to define the callback contract. Below will be one solution
class HelloWorld {
static class PerformLongOperation {
public void doTask(IOnTaskUpdateCallback onTaskUpdatedCallback) {
onTaskUpdatedCallback.onProgressUpdated(0);
for (int i = 10; i <= 100; i+=10) {
try {
// add sleep to show task is being done
Thread.sleep(1000);
} catch (InterruptedException exp) {
// ignoring for now
}
onTaskUpdatedCallback.onProgressUpdated(i);
}
}
}
interface IOnTaskUpdateCallback {
// called when any update in the progress
void onProgressUpdated(int progress);
}
public static void main(String[] args) {
PerformLongOperation longGoing = new PerformLongOperation();
longGoing.doTask(new IOnTaskUpdateCallback() {
@Override
public void onProgressUpdated(int progress) {
System.out.println("Progress is: " + progress);
}
});
}
}
Solution 1.1: Using interface and lambda
We can make our main()
method more concise by using lambda like below
public static void main(String[] args) {
PerformLongOperation longGoing = new PerformLongOperation();
longGoing.doTask(progress -> System.out.println("Progress is: " + progress));
}
Solution 2: Using Consumer
Since, IOnTaskUpdateCallback
satisfies all condition for being a Consumer, we can just use Consumer
rather than defining a new one new interface.
class HelloWorld {
static class PerformLongOperation {
public void doTask(Consumer<Integer> onTaskUpdatedCallback) {
onTaskUpdatedCallback.accept(0);
for (int i = 10; i <= 100; i+=10) {
try {
// add sleep to show task is being done
Thread.sleep(1000);
} catch (InterruptedException exp) {
// ignoring for now
}
onTaskUpdatedCallback.accept(i);
}
}
}
public static void main(String[] args) {
PerformLongOperation longGoing = new PerformLongOperation();
longGoing.doTask(progress -> System.out.println("Progress is: " + progress));
}
}
To sum up, the Consumer functional interface in Java simplifies coding, enhances reusability, and streamlines development, making it a valuable tool for efficient programming.
Subscribe to my newsletter
Read articles from Sajal Raj Gautam directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Sajal Raj Gautam
Sajal Raj Gautam
I’m a software engineer with a focus on Android applications and framework development. I specialize in tackling complex challenges with innovative solutions. I’ve worked across various form factors and software layers, contributing to the various software development lifecycle—design, development, testing, planning, and performance optimization. Leading teams, I ensure quality deliverables within deadlines. Beyond Android, I’ve gained hands-on experience in Robotics, IoT devices, RTOS applications, and Machine Learning. My dynamic career journey reflects my enthusiasm for learning and adapting to new technologies. I’m eager to explore opportunities and contribute to cutting-edge developments in the tech industry.