Consumer and BiConsumer Functional Interface
Consumer<T>
is an
in-built functional interface introduced in Java 8 in the java.util.function
package. It
can be used in all contexts where an object needs to be consumed, i.e. taken as
input, and some operation is to be performed on the object without returning
any result.
Common example of such an operation is printing where an
object is taken as input to the printing function and the value of the object
is printed.
The functional method of Consumer is accept(T t).
@FunctionalInterface
Public interface Consume<T,
> { …}
Here is a simple source code of java.util.function.Consumer
package
java.util.function;
import
java.util.Objects;
@FunctionalInterface
public interface Function<T>
{
public void accept(T t);
}
Where
accept (T t) is an abstract method where T is the type of the input to the Function.
Example 1:
import java.util.function.Consumer;
public class ConsumerExample {
public static void main(String[] args) {
// Calling
Consumer Functional Interface without using Lambda Expression
SendNotification notification = new SendNotification();
notification.accept("Abdul");
// Using
Lambda Expression
Consumer<String> consumer = username -> System.out.println("Send mail notification to :
" + username);
consumer.accept("Waheed");
}
}
class SendNotification implements Consumer<String> {
@Override
public void accept(String user) {
System.out.println("Send mail notification to : " + user);
}
}
Output:
Send
mail notification to : Abdul
Send
mail notification to : Waheed
Example 2:
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
public class ConsumerExample2 {
public static void main(String[] args) {
ConsumerExample2 consumerExample2 = new ConsumerExample2();
Consumer<Student> consumer = student -> {
System.out.println("Name: " + student.getName());
System.out.println("Age: " + student.getAge());
System.out.println("================================");
};
List<Student> students = consumerExample2.populateStudentList();
for (Student student : students) {
consumer.accept(student);
}
}
public List<Student> populateStudentList() {
List<Student> studentList = Arrays.asList(new Student("Abdul", 31), new Student("Waheed", 29),
new Student("DummyUser", 20), new Student("Adam", 25));
return studentList;
}
}
class Student {
private String name;
private int age;
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public boolean equals(Object obj) {
Student student = (Student) obj;
if ((this.getName().equals(student.getName()) && this.getAge() == student.getAge())) {
return true;
} else {
return false;
}
}
}
Output:
Name:
Abdul
Age: 31
================================
Name:
Waheed
Age: 29
================================
Name:
DummyUser
Age: 20
================================
Name:
Adam
Age: 25
================================
Example 3:
In this example, I’ll use Predicate,
Function and Consumer for better understanding. Below Program will print Student
detail with its grade (Generate Grade based on marks) who marks are greater
than 60%.
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.Function;
/**
* Use of Predicate, Function and Consumer
Functional Interface in one class;
*
* It will print name of the student who has
marks greater than 60% with its
* GRADE.
*
* @author Abdul Waheed
*
*/
public class ConsumerExample3 {
public static void main(String[] args) {
ConsumerExample3 consumerExample3 = new ConsumerExample3();
Predicate<Stud> p1 = student -> student.getMarks() > 60;
Function<Stud, String> f1 = student -> {
int marks = student.getMarks();
if (marks > 80) {
return "A";
} else if (marks > 70) {
return "B";
} else if (marks > 60) {
return "C";
} else {
return "E";
}
};
// Internally
invoking Function interface
Consumer<Stud> c1 = student -> {
System.out.println("Name: " + student.getName());
System.out.println("Marks: " + student.getMarks());
System.out.println("Grade: " + f1.apply(student));
System.out.println("================================");
};
List<Stud> students = consumerExample3.populateStudentList();
for (Stud stud : students) {
if (p1.test(stud)) {
c1.accept(stud);
}
}
}
public List<Stud> populateStudentList() {
List<Stud> studentList = Arrays.asList(new Stud("Abdul", 31, 60), new Stud("Waheed", 29, 90),
new Stud("DummyUser", 20, 80), new Stud("Adam", 25, 47));
return studentList;
}
}
class Stud {
private String name;
private int age;
private int marks;
public Stud(String name, int age, int marks) {
super();
this.name = name;
this.age = age;
this.marks = marks;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getMarks() {
return marks;
}
public void setMarks(int marks) {
this.marks = marks;
}
public boolean equals(Object obj) {
Student student = (Student) obj;
if ((this.getName().equals(student.getName()) && this.getAge() == student.getAge())) {
return true;
} else {
return false;
}
}
}
Output:
Name:
Waheed
Marks:
90
Grade: A
================================
Name:
DummyUser
Marks:
80
Grade: B
================================
Apart from accept (T t) method, Consumer also has only one default method.
Modifier and Type
|
Method and
Description
|
Returns a composed Consumer that
performs, in sequence, this operation followed by the after operation.
|
We can use andThen(Consumer<? super T> after) for Consumer
Chaining i.e. we can call multiple Consumer Function at the same time.
C1.andThen(C2).andThen(C3).accept(“Student);
Over here, first C1 will be called
then C2 and then C3.
Let’s understand with an example
where if a new student register to a website, then data should be updated to
database and send welcome mail to User as well.
Example 3:
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
public class ConsumerChainning {
public static void main(String[] args) {
ConsumerChainning chainning = new ConsumerChainning();
Consumer<Student> addToDB = Student -> {
System.out.println("Open Database Connection");
System.out.println("Write Record to DB");
System.out.println("Name: " + Student.getName() + ", Age: " + Student.getAge());
System.out.println("Close Connection");
System.out.println("================================");
};
Consumer<Student> sendMail = Student -> {
System.out.println("Configure Mail Server");
System.out.println("Send Mail to user " + Student.getName());
System.out.println("================================\n");
};
List<Student> students = chainning.populateStudentList();
for (Student student : students) {
addToDB.andThen(sendMail).accept(student);
}
}
public List<Student> populateStudentList() {
List<Student> studentList = Arrays.asList(new Student("Abdul", 31), new Student("Waheed", 29),
new Student("DummyUser", 20), new Student("Adam", 25));
return studentList;
}
}
Output:
Open
Database Connection
Write
Record to DB
Name:
Abdul, Age: 31
Close
Connection
================================
Configure
Mail Server
Send
Mail to user Abdul
================================
Open
Database Connection
Write
Record to DB
Name:
Waheed, Age: 29
Close
Connection
================================
Configure
Mail Server
Send
Mail to user Waheed
================================
Open
Database Connection
Write
Record to DB
Name:
DummyUser, Age: 20
Close
Connection
================================
Configure
Mail Server
Send
Mail to user DummyUser
================================
Open
Database Connection
Write
Record to DB
Name:
Adam, Age: 25
Close
Connection
================================
Configure
Mail Server
Send
Mail to user Adam
================================
BiConsumer Functional Interface
It is very similar to Consumer Functional
Interface. The only difference is just that it will accept two input arguments instead
of one and will return nothing
@FunctionalInterface
public interface BiConsumer<T,U> {
accept(T
t, U u);
}
Let’s see an example
Example 4:
import java.util.function.BiConsumer;
public class BiConsumerExample {
public static void main(String[] args) {
BiConsumer<String, String> fullName = (fn, ln) ->
System.out.println(fn.concat(" " + ln));
fullName.accept("Abdul", "Waheed");
}
}
Output:
Abdul
Waheed
That’s it for Consumer and BiConsumer
Functional Interface, Will talk about other Predefined Functional Interface in
my next blog.
Happy Coding…!!!