# Consumer interface in Java

The `Consumer` interface was introduced in Java 1.8. Below is a an excerpt from the official [documentation](https://docs.oracle.com/javase/8/docs/api/java/util/function/Consumer.html)
> 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)`.
```java
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
1. The behavior (accept method) of the consumer interface is well known. As a result, it increases the readability of the code.
2. Enhances code reusability by leveraging pre-existing interfaces rather than creating custom ones for the same behavior.
3. As it is a [functional interface](https://docs.oracle.com/javase/8/docs/api/java/lang/FunctionalInterface.html), it can be efficiently defined using lambda expressions.
4. The `Consumer` interface is commonly utilized in many new Java methods, such as those found in the [`Stream`](https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html) class.
5. The `Consumer` instances can be executed sequentially by utilizing the `andThen` 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
```java
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
```java
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.
```java
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.

