Introduction
Here you can learn what is Consumer and Supplier interfaces of java8 and its real uses in application development. To understand these two functional interfaces you must have at least basic idea on lambda functions in java8.When we can use Consumer interface
For better understanding of real usage of Consumer interface let us consider a situation in application development as described bellow.
In a restaurant menu display application we are going to display available menu items category wise. There are three categories of menus. Each category has more than one food item. As a result of the application we need to display available food items on the screen. Here we are going to create core java application. Here we are going to develop food items display logic as a lambda function.
Logic implementation without Consumer interface : used inline lambda functions |
In the above you can see that there are three inline lambda functions are created. You can notice that almost logic part of three inline codeblocks of lambda functions are same. If we want to change the logic then we have to make changes in three codeblocks for sure. So this is a problem ( changing logic in three different codeblock locations). To over come this issue we can use Consumer interface.
Consumer Interface as Assignment target for lambda function |
In the above you can notice that we have created menuAction object for Consumer interface(which used as Assignment Target for lambda function). We have used menuAction object as a parameter to foeEach() method on each list object. Once we done changes in one codeblock location then it will be affected on three forEach() locations.
package info.code123.lambda; import java.util.ArrayList; import java.util.List; public class RestaurentMenu { public static void main(String[] args) { List<FoodItem> vegList = new ArrayList<FoodItem>(); vegList.add(new FoodItem("veg1", "Idly", 20)); vegList.add(new FoodItem("veg2", "Dosa", 25)); vegList.add(new FoodItem("veg3", "vada", 30)); vegList.forEach(vlObject -> { System.out.print("Item Code:" + vlObject.getItemCode()); System.out.print("Item Name:" + vlObject.getItemName()); System.out.println("Item Price:" + vlObject.getItemPrice()); }); System.out.println("***************************************"); List<FoodItem> nonVegList = new ArrayList<FoodItem>(); nonVegList.add(new FoodItem("nv1", "chicken Fry", 20)); nonVegList.add(new FoodItem("nv2", "Mutton Kheema", 25)); nonVegList.forEach(nvlObject -> { System.out.print("Item Code:" + nvlObject.getItemCode()); System.out.print("Item Name:" + nvlObject.getItemName()); System.out.println("Item Price:" + nvlObject.getItemPrice()); }); System.out.println("***************************************"); List<FoodItem> chatList = new ArrayList<FoodItem>(); chatList.add(new FoodItem("c1", "samosa", 20)); chatList.add(new FoodItem("c2", "Gupchup", 25)); chatList.forEach(clObject -> { System.out.print("Item Code:" + clObject.getItemCode()); System.out.print("Item Name:" + clObject.getItemName()); System.out.println("Item Price:" + clObject.getItemPrice()); }); } }In the above snippet of the code we have implemented the logic without Consumer interface. In the following snippet of the code we are rewriting the same logic with Consumer interface as assignment target to lambda function.
Consumer<FoodItem> menuAction = fitem -> { System.out.print("Item Code:" + fitem.getItemCode()); System.out.print("Item Name:" + fitem.getItemName()); System.out.println("Item Price:" + fitem.getItemPrice()); }; List<FoodItem> vegList = new ArrayList<FoodItem>(); vegList.add(new FoodItem("veg1", "Idly", 20)); vegList.add(new FoodItem("veg2", "Dosa", 25)); vegList.add(new FoodItem("veg3", "vada", 30)); vegList.forEach(menuAction); System.out.println("***************************************"); List<FoodItem> nonVegList = new ArrayList<FoodItem>(); nonVegList.add(new FoodItem("nv1", "chicken Fry", 20)); nonVegList.add(new FoodItem("nv2", "Mutton Kheema", 25)); nonVegList.forEach(menuAction); System.out.println("***************************************"); List<FoodItem> chatList = new ArrayList<FoodItem>(); chatList.add(new FoodItem("c1", "samosa", 20)); chatList.add(new FoodItem("c2", "Gupchup", 25)); chatList.forEach(menuAction);In the above code we have implemented Consumer interface from line 1 to 5. Consumer reference menuAction is passing as argument to forEach() method.
We cannot use menuAction in other class, because it is created for using in current class only. To use menuAction in other class we need to create a class which implements Consumer interface.
Implementing Consumer interface
Now we will see the components of Consumer interface. Consumer interface is a functional interface which has only one abstract method, and apart from abstract method functional interface may has default methods
-
public interface Consumer<T>
@FunctionalInterface public interface Consumer<T>
This is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference.
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
Type Parameters:accept(Object)
.T
- the type of the input to the operation- This is available from :
- java 1.8
-
accept ( abstract method of Consumer interface )
void accept(T t)
Performs this operation on the given argument. The logic written in the implementation of this method will be executed when we pass Consumer object as a parameter to the stream methods for example forEach()- Parameters:
t
- the input argument
-
andThen ( default method of Consumer interface )
default Consumer<T> andThen(Consumer<? super T> after)
Returns a composedConsumer
that performs, in sequence, this operation followed by theafter
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, theafter
operation will not be performed.- Parameters:
after
- this is a Consumer object which is the operation to perform after current operation- Returns:
- a composed
Consumer
that performs in sequence this operation followed by theafter
operation - Throws:
NullPointerExceptionM
- if after is null
import java.util.function.Consumer; public class FoodItemConsumer implements Consumer<FoodItem> { @Override public void accept(FoodItem fitem) { System.out.print("Item Code:" + fitem.getItemCode()); System.out.print("Item Name:" + fitem.getItemName()); System.out.println("Item Price:" + fitem.getItemPrice()); } }We can use the object of FoodItemConsumer as a assignment target to lambda function. So just create an object for FoodItemConsumer whereever you want to use it.
import java.util.ArrayList; import java.util.List; import java.util.function.Consumer; import javax.sound.sampled.LineListener; public class RestaurentMenu { public static void main(String[] args) { FoodItemConsumer menuAction= new FoodItemConsumer(); List<FoodItem> vegList = new ArrayList<FoodItem>(); vegList.add(new FoodItem("veg1", "Idly", 20)); vegList.add(new FoodItem("veg2", "Dosa", 25)); vegList.add(new FoodItem("veg3", "vada", 30)); vegList.forEach(menuAction); System.out.println("***************************************"); List<FoodItem> nonVegList = new ArrayList<FoodItem>(); nonVegList.add(new FoodItem("nv1", "chicken Fry", 20)); nonVegList.add(new FoodItem("nv2", "Mutton Kheema", 25)); nonVegList.forEach(menuAction); System.out.println("***************************************"); List<FoodItem> chatList = new ArrayList<FoodItem>(); chatList.add(new FoodItem("c1", "samosa", 20)); chatList.add(new FoodItem("c2", "Gupchup", 25)); chatList.forEach(menuAction); } }In the above class we have created an object for FoodItemConsumer and we are using that as an argument to forEach() at three locations.
We can use Consumer class if we want to pass lambda function as an argument in other locations ( methods like forEach() ). We can use one parameter for lambda function, on which logic/action has to be applied. Consumer cannot return any result.
Supplier Interface
We can use supplier interface if we want a no argument lambda function which returns some results.
-
public interface Supplier<T>
- Type Parameters:
T
- the type of results supplied by this supplier
- This is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference.
@FunctionalInterface public interface Supplier<T>
Represents a supplier of results.There is no requirement that a new or distinct result be returned each time the supplier is invoked.
This is a functional interface whose functional method is
get()
.
-
get ( functional method or abstract method of Supplier interface)
T get()
Gets a result.- Returns:
- a result
Supplier<FoodItemConsumer> sup= () ->{return new FoodItemConsumer();}; FoodItemConsumer menuAction= sup.get();
There is no big use with Supplier interface except making easiness to access an object or no argument methods of a class which returns same class object as a result
Post a Comment
Post a Comment