An easy way to understand Consumer interface in Java 8.
The Consumer interface is a part of the java.util.function package introduced in Java 8.
It is a functional interface in Java.
It represents an operation that takes a single input argument of a specified type, and returns no result.
It has only one abstract method, accept(T t) which is used to perform the operation on the given input.Also it has andThen(Consumer<? super T> after) default method.
void accept(T t)
T= Generic Type Placeholder: Example String, int etc
t=Argument Variable : Example name, age etc
The andThen method
It is a default method introduced in the Consumer interface in Java 8.
It allows you to combine two Consumer instances in a chain, where the second consumer is executed after the first one.
The andThen method returns a new Consumer that represents the combination of the two original consumers.
The andThen method is designed to work with consumers of the same type. So String and int cant be combined.
@FunctionalInterface
public interface Consumer<T> {
// Abstract method for accepting a value
void accept(T t);
// Default method for composing two consumers
default Consumer<T> andThen(Consumer<? super T> after) {
// Ensure that the 'after' consumer is not null
Objects.requireNonNull(after);
// Return a new consumer that first applies the current consumer and then the 'after' consumer
return (T t) -> {
accept(t); // Apply the current consumer
after.accept(t); // Apply the 'after' consumer
};
}
}
Before using Lambdas and streams, let’s look at the tradional way .
Here I use the traditional way of implementing the Consumer interface by creating a class (ConsumerSimple) that explicitly implements the accept method.
In this case, the ConsumerSimple class implements the Consumer interface, and the accept method is overridden to specify what action should be taken when the accept method is called.
package com.exercise.consumerinterface;
import java.util.function.Consumer;
public class ConsumerSimple implements Consumer {
@Override
public void accept(Object o) {
// Our custom code here.
System.out.println(o);
}
public static void main(String[] args) {
// Create an instance of ConsumerSimple
ConsumerSimple cs1 = new ConsumerSimple();
// Call the accept method on cs1
cs1.accept("Accept me and return none.");
}
}
This will give below output.
Accept me and return none.
Now slowly jump in to use Consumer interface with lambda expressions
Create a basic Consumer of type String using lambda expressions.
Understand how the accept method prints provided strings.
Advanced Usage with andThen:
Leverage the andThen method of the Consumer interface.
How to use forEach with both Lambda expression and Consumer interface and just lambda expression only.
package com.exercise.consumerinterface;
import java.sql.Array;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
public class ConsumerJavaEightWay {
public static void main(String[] args) {
/* Creating a Consumer of type String in Consumer<String> cs1
The lambda expression specifies that this consumer takes an argument of type String.
When you use cs1.accept("someString"), it will print the provided string.
*/
Consumer<String> cs1 = o -> System.out.println(o);
// We can also assign a default value, for example: System.out.println("my default String value.");
Consumer<String> cs2 = o -> System.out.println(o);
// Calling accept on cs1 with the argument "Hello"
cs1.accept("Hello");
// Calling accept on cs2 with the argument "Darkness"
cs2.accept("Darkness");
/*
Instead of calling the accept method twice, we can leverage the default andThen method in the Consumer interface.
*/
// To demonstrate this, I'll create two consumers with default string values.
Consumer<String> firstConsumer = s -> System.out.println("English consumer says: " + s + " Burger.");
Consumer<String> secondConsumer = s -> System.out.println("Spanish consumer says: " + s + " Hamburguesa.");
// Combine the consumers using andThen to create a new consumer
Consumer<String> combinedConsumer = firstConsumer.andThen(secondConsumer);
// Call the accept method on the combined consumer
combinedConsumer.accept("I need a ");
// Define a String List which contains capitals .
List<String> capitals= Arrays.asList("Paris","London","Munich","Madrid","Havana");
/*
in foreach method , even we provide a list , at each iteration, there will be only one String value
So we can define a String List and pass it.
The forEach method internally calls the accept method in the Consumer interface and passes the given String value.
*/
capitals.forEach(cs1);
System.out.println("Instead of using consumer interface, we can directly pass the lambda expression only.");
/*
you can directly pass the lambda expression to the forEach method without explicitly creating a Consumer instance.
In fact, that's a common and concise way to use forEach with a lambda expression.
*/
//How to use forEach with just lambda expression only.
capitals.forEach(o -> System.out.println(o));
}
}
This will give below output.
Hello
Darkness
English consumer says: I need a Burger.
Spanish consumer says: I need a Hamburguesa.
Paris
London
Munich
Madrid
Havana
Instead of using consumer interface, we can directly pass the lambda expression only.
Paris
London
Munich
Madrid
Havana
Further reference-https://www.youtube.com/watch?v=Tapz6_T5oHY&t=676s