Consumer’s in java8

Introduction

Consumer’s are functional interfaces which takes an argument as a parameter and returns nothing.It defines an abstract method accept() and returns void.They can also be used as an assignment target for lambda expression or method references.

Java Doc:

@FunctionalInterface
Interface Consumer<T>{
void accept(T t)
}

Consumer’s Code example :

In the below example , the consumer printIt takes a string argument.It just prints the argument in the console.

package com.ppkcodes.examples;

import java.util.function.Consumer;

public class ConsumerExample {
    public static void main(String[] args) {
        Consumer printIt=(str)-> System.out.println(str);

        printIt.accept("Pramod");
        printIt.accept("Hello");
        printIt.accept("How are you?");
    }
}
Output:
Pramod
Hello
How are you?

Looping example with Consumer:

Now lets take a look at a looping use case with Consumer.Ill explain the drawbacks of traditional loops and why its better to loop with a Consumer.Ill create a new ArrayList and print them in different ways.

//Initialize and set an array
List<String> namesList= Arrays.<em>asList</em>("Sachin","Sourav","Sehwag","Dravid","Zaheer");

Traditional For loop:

System.<em>out</em>.println(" Traditional For loop Output-->");
for (int i = 0; i < namesList.size(); i++)
System.<em>out</em>.println(namesList.get(i));

This way of looping an arrayList is verbose .This does not use an iterator too hence the clients using this data structure must know the implementation of ArrayList. Moreover this type of loop is only useful if you have to manipulate data at a specific index.Hence not a great idea to use them.

ForLoop using Iterator:

System.<em>out</em>.println(" For loop using an iterator");
for (String name : namesList) {
System.<em>out</em>.println(name);
}

This looping technique uses an iterator . Clients using this need not know the underlying implementation of the data structure.Which is why iterator pattern was introduced. Its better performing than the traditional for loop but there are few things which I don’t like about this :

  • for Loop is sequential and difficult to achieve parallelism.
  • Instead of invoking a method on the List , we are passing the List to the for loop .Such an operation is non-polymorphic.
  • It fails “Tell,don’t ask” principle. You are asking the for loop to perform an iteration in a certain way. It should have been encapsulated by another method which should be responsible to handle the details of the iteration.

Using Consumer with Lambda:

System.<em>out</em>.println(" For each loop using Consumer and Lambda");
Consumer<String> printName=strName-> System.<em>out</em>.println(strName);
namesList.forEach(str->printName.accept(str));

Look at the third approach for looping the List.This made the code to look less verbose and elegant.It also uses a forEach() loop which is a higher order function.The accept() method encapsulates the underlying details of what to do with the collection.Its an ideal use case for using Consumers.

All put in together, observe easy it is to use a consumer with forEach for looping.

package com.codingbrains.examples;

import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;

public class ConsumerLoopingExample {

  public static void main(String[] args) {
    //Initialize and set an array
    List<String> namesList= Arrays.asList("Sachin","Sourav","Sehwag","Dravid","Zaheer");
    //Traditional for loop
    System.out.println(" Traditional For loop Output-->");
    for (int i = 0; i < namesList.size(); i++)
      System.out.println(namesList.get(i));

    //For loop using an iterator
    System.out.println(" For loop using an iterator-->");
    for (String name : namesList) {
      System.out.println(name);
    }

    //For each loop using lambda
    System.out.println(" For each loop using Consumer and Lambda-->");
    Consumer<String> printName=strName-> System.out.println(strName);
    namesList.forEach(str->printName.accept(str));
  }
}
Traditional For loop Output-->
Sachin
Sourav
Sehwag
Dravid
Zaheer
For loop using an iterator-->
Sachin
Sourav
Sehwag
Dravid
Zaheer
For each loop using Consumer and Lambda-->
Sachin
Sourav
Sehwag
Dravid
Zaheer

Primitive Variants

Consumer‘s in Java8 have their primitive variants too .They are :

  1. IntConsumer
  2. LongConsumer
  3. DoubleCousumer

Credits: Functional Programming in Java.

You may also like...

Leave a Reply

Your email address will not be published.