Deep dive into Optional class API in Java 8

We all as Java programmers been through the situation where in we invoke a method to get some value and then instead of directly invoking some methods on the return value, we first have to check that the return value is not null and then invoke the methods on the return value. This has been a pain point which external APIs like Guava have tried to solve. Also alternate JVM languages like Scala, Ceylon and others have this features baked right into the core APIs. In my previous post I wrote about support in one such JVM language namely Scala.

The newer version of Java i.e Java 8 introduces a new class called Optional. The Javadoc for Optional class says:

A container object which may or may not contain a non-null value. If a value is present, isPresent() will return true and get() will return the value.

In this post lets go through each of the methods present in Optional class and explain the same with an example or two.

of

Returns an Optional with the specified present non-null value.

This method is a factory method for creating instances of Optional class. Something to take note of here is that the value being passed to created the instance has to be non-null. If the value passed is null then a NullPointerException is thrown.

//Creating an instance of Optional using the factory method.
Optional<String> name = Optional.of("Sanaulla");
//This fails with a NullPointerException.
Optional<String> someNull = Optional.of(null);

ofNullable

Returns an Optional describing the specified value, if non-null, otherwise returns an empty Optional.

Similar to the of method, the only difference is that this method handles null values as well. An example:

//This represents an instance of Optional containing no value
//i.e the value is 'null'
Optional empty = Optional.ofNullable(null);

isPresent

Very simple to understand:

Return true if there is a value present, otherwise false.

Something like:

//isPresent method is used to check if there is any 
//value embedded within the Optional instance.
if (name.isPresent()) {
  //Invoking get method returns the value present
  //within the Optaional instance.
  System.out.println(name.get());//prints Sanaulla
}

get

If a value is present in this Optional, returns the value, otherwise throws NoSuchElementException.

This method is used to retrieve the value present in the Optional instance. We saw one such example above. Lets look at an example where a NoSuchElementException is thrown:

//The below code prints: No value present 
try {
  //Invoking get method on an empty Optaional instance 
  //throws NoSuchElementException.
  System.out.println(empty.get());
} catch (NoSuchElementException ex) {
  System.out.println(ex.getMessage());
}

ifPresent

If a value is present, invoke the specified consumer with the value, otherwise do nothing.

To understand this method you would have to understand about the Consumer class. In short Consumer is a class with single abstract method to consumer some value and perform some operation on it without returning any value. In Java 8 one can pass a lambda expression to the method expecting an implementation of Consumer interface.
The above method accepts an block of code/lambda expression to perform some operation if the value is present in the Optional instance. Something like:

//ifPresent method takes a lambda expression as a parameter.
//The lambda expression can then consume the value if it is present
//and perform some operation with it.
name.ifPresent((value) -> {
  System.out.println("The length of the value is: " + value.length());
});

orElse

Return the value if present, otherwise return other.

This method either returns the value present in the Optional instance and if not it returns the value passed as a parameter to the orElse method. Lets look at an example:

//orElse method either returns the value present in the Optional instance
//or returns the message passed to the method in case the value is null.
//prints: There is no value present!
System.out.println(empty.orElse("There is no value present!"));
//prints: Sanaulla
System.out.println(name.orElse("There is some value!"));

orElseGet

This method is similar to the above method. The difference is in how the default value is obtained. In the orElse method we pass a fixed string as the default value, but in orElseGet method we pass an implementation of Supplier interface which has a method which is used to generate the default value. Lets look at an example:

//orElseGet is similar to orElse with a difference that instead of passing 
//a default value, we pass in a lambda expression which generates the default 
//value for us.
//prints: Default Value
System.out.println(empty.orElseGet(() -> "Default Value"));
//prints: Sanaulla
System.out.println(name.orElseGet(() -> "Default Value"));

orElseThrow

Return the contained value, if present, otherwise throw an exception to be created by the provided supplier.

Just like in the method orElseGet we pass a Supplier interface, but in orElseThrow method we pass a lambda expression/method reference to throw an exception when the value is not found. An example for this:


try {
  //orElseThrow similar to orElse method, instead of returning a default
  //value, this method throws an exception which is generated from 
  //the lambda expression/method reference passed as a param to the method.
  empty.orElseThrow(ValueAbsentException::new);
} catch (Throwable ex) {
  //prints: No value present in the Optional instance
  System.out.println(ex.getMessage());
}

And the definition for ValueAbsentException is:

class ValueAbsentException extends Throwable {

  public ValueAbsentException() {
    super();
  }

  public ValueAbsentException(String msg) {
    super(msg);
  }

  @Override
  public String getMessage() {
    return "No value present in the Optional instance";
  }
}

map

From the documentation for map method:

If a value is present, apply the provided mapping function to it, and if the result is non-null, return an Optional describing the result. Otherwise return an empty Optional.

This method is used to apply a set of operations on the value present in the Optional instance. The set of operations are passed in the form of a lambda expression representing an implementation of the Function interface. If you are not familiar with the Function interface, then please spend some time reading my earlier blog post on the same topic here. Lets look at an example for the map method:

//map method modifies the value present within the Optional instance
//by applying the lambda expression passed as a parameter. 
//The return value of the lambda expression is then wrapped into another
//Optional instance.
Optional<String> upperName = name.map((value) -> value.toUpperCase());
System.out.println(upperName.orElse("No value found"));

flatMap

From the documentation for the flatMap method:

If a value is present, apply the provided Optional-bearing mapping function to it, return that result, otherwise return an empty Optional. This method is similar to map(Function), but the provided mapper is one whose result is already an Optional, and if invoked, flatMap does not wrap it with an additional Optional.

This method is very similar to map method and differs from it in the return type of the mapping function passed to it. In the case of map method the mapping function return value can be of any type T, where as in case of flatMap method the return value of the mapping function can only be of type Optional.

Lets look at the above example for map method being re-written for flatMap method:

//flatMap is exactly similar to map function, the differece being in the
//return type of the lambda expression passed to the method.
//In the map method, the return type of the lambda expression can be anything
//but the value is wrapped within an instance of Optional class before it 
//is returned from the map method, but in the flatMap method the return 
//type of lambda expression's is always an instance of Optional.
upperName = name.flatMap((value) -> Optional.of(value.toUpperCase()));
System.out.println(upperName.orElse("No value found"));//prints SANAULLA

filter

This method is used to restrict the value within an Optional instance by passing the condition to be applied on the value to the filter method. The documentation says:

If a value is present, and the value matches the given predicate, return an Optional describing the value, otherwise return an empty Optional.

By now you must have got an idea of how to pass some block of code to the method. Yes, it is a lambda expression. In the case of this method we have to pass a lambda expression which would be an implementation of the Predicate interface. If you are not familiar with the Predicate interface, then please take some time to read this post.

Now lets look at different usages of filter method i.e both examples of condition being satisfied and condition not being satisfied.

//filter method is used to check if the given optional value satifies
//some condtion. If it satifies the condition then the same Optional instance
//is returned, otherwise an empty Optional instance is returned.
Optional<String> longName = name.filter((value) -> value.length() > 6);
System.out.println(longName.orElse("The name is less than 6 characters"));//prints Sanaulla

//Another example where the value fails the condition passed to the 
//filter method.
Optional<String> anotherName = Optional.of("Sana");
Optional<String> shortName = anotherName.filter((value) -> value.length() > 6);
//prints: The name is less than 6 characters
System.out.println(shortName.orElse("The name is less than 6 characters"));

With this I have introduced you to the various methods present in the Optional class. Let me aggregate all the above examples into one single example shown below:

public class OptionalDemo {

  public static void main(String[] args) {
    //Creating an instance of Optional
    //This value can also be returned from some method. 
    Optional<String> name = Optional.of("Sanaulla");

    //This represents an instance of Optional containing no value
    //i.e the value is 'null'
    Optional empty = Optional.ofNullable(null);

    //isPresent method is used to check if there is any 
    //value embedded within the Optional instance.
    if (name.isPresent()) {
      //Invoking get method returns the value present
      //within the Optaional instance.
      System.out.println(name.get());

    }

    try {
      //Invoking get method on an empty Optaional instance 
      //throws NoSuchElementException.
      System.out.println(empty.get());
    } catch (NoSuchElementException ex) {
      System.out.println(ex.getMessage());
    }

    //ifPresent method takes a lambda expression as a parameter.
    //The lambda expression can then consume the value if it is present
    //and perform some operation with it.
    name.ifPresent((value) -> {
      System.out.println("The length of the value is: " + value.length());
    });

    //orElse method either returns the value present in the Optional instance
    //or returns the message passed to the method in case the value is null.
    System.out.println(empty.orElse("There is no value present!"));
    System.out.println(name.orElse("There is some value!"));

    //orElseGet is similar to orElse with a difference that instead of passing 
    //a default value, we pass in a lambda expression which generates the default 
    //value for us.
    System.out.println(empty.orElseGet(() -> "Default Value"));
    System.out.println(name.orElseGet(() -> "Default Value"));

    try {
      //orElseThrow similar to orElse method, instead of returning a default
      //value, this method throws an exception which is genereated from 
      //the lambda expression/method reference passed as a param to the method.
      empty.orElseThrow(ValueAbsentException::new);
    } catch (Throwable ex) {
      System.out.println(ex.getMessage());
    }
    
    //map method modifies the value present within the Optional instance
    //by applying the lambda expression passed as a parameter. 
    //The return value of the lambda expression is then wrapped into another
    //Optional instance.
    Optional<String> upperName = name.map((value) -> value.toUpperCase());
    System.out.println(upperName.orElse("No value found"));
    
    //flatMap is exactly similar to map function, the differece being in the
    //return type of the lambda expression passed to the method.
    //In the map method, the return type of the lambda expression can be anything
    //but the value is wrapped within an instance of Optional class before it 
    //is returned from the map method, but in the flatMap method the return 
    //type of lambda expression's is always an instance of Optional.
    upperName = name.flatMap((value) -> Optional.of(value.toUpperCase()));
    System.out.println(upperName.orElse("No value found"));
    
    //filter method is used to check if the given optional value satifies
    //some condtion. If it satifies the condition then the same Optional instance
    //is returned, otherwise an empty Optional instance is returned.
    Optional<String> longName = name.filter((value) -> value.length() > 6);
    System.out.println(longName.orElse("The name is less than 6 characters"));
    
    //Another example where the value fails the condition passed to the 
    //filter method.
    Optional<String> anotherName = Optional.of("Sana");
    Optional<String> shortName = anotherName.filter((value) -> value.length() > 6);
    System.out.println(shortName.orElse("The name is less than 6 characters"));

  }

}

And the output of the above code:

Sanaulla
No value present
The length of the value is: 8
There is no value present!
Sanaulla
Default Value
Sanaulla
No value present in the Optional instance
SANAULLA
SANAULLA
Sanaulla
The name is less than 6 characters

Strategy Pattern using Lambda Expressions in Java 8

Strategy Pattern is one of the patterns from the Design Patterns : Elements of Reusable Object book. The intent of the strategy pattern as stated in the book is:

Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.

In this post I would like to give an example or two on strategy pattern and then rewrite the same example using lambda expressions to be introduced in Java 8.

Strategy Pattern: An example

Consider an interface declaring the strategy:

interface Strategy{
  public void performTask();
}

Consider two implementations of this strategy:

class LazyStratgey implements Strategy{

  @Override
  public void performTask() {
    System.out.println("Perform task a day before deadline!");
  }
  
}

class ActiveStratgey implements Strategy{

  @Override
  public void performTask() {
    System.out.println("Perform task now!");
  }
  
}

The above strategies are naive and I have kept it simple to help readers grasp it quickly. And lets see these strategies in action:

public class StartegyPatternOldWay {

  public static void main(String[] args) {

    List<Strategy> strategies = 
        Arrays.asList(
          new LazyStratgey(), 
          new ActiveStratgey()
        );
                      
    for(Strategy stg : strategies){
      stg.performTask();
    }
  }
}

The output for the above is:

Perform task a day before deadline!
Perform task now!

Strategy Pattern: An example with Lambda expressions

Lets look at the same example using Lambda expressions. For this we will retain our Strategy interface, but we need not create different implementation of the interface, instead we make use of lambda expressions to create different implementations of the strategy. The below code shows it in action:

import java.util.Arrays;
import java.util.List;

public class StrategyPatternOnSteroids {
  public static void main(String[] args) {
      
    System.out.println("Strategy pattern on Steroids");
    
    List<Strategy> strategies = 
      Arrays.asList(
        () -> {System.out.println("Perform task a day before deadline!");},
        () -> {System.out.println("Perform task now!");}
      );
    
    strategies.forEach((elem) -> elem.performTask());
  }
  
}

The output for the above is:

Strategy pattern on Steroids
Perform task a day before deadline!
Perform task now!

In the example using lambda expression, we avoided the use of class declaration for different strategies implementation and instead made use of the lambda expressions.

Strategy Pattern: Another Example

This example is inspired from Neal Ford’s article on IBM Developer works: Functional Design Pattern-1. The idea of the example is exactly similar, but Neal Ford uses Scala and I am using Java for the same with a few changes in the naming conventions.

Lets look at an interface Computation which also declares a generic type T apart from a method compute which takes in two parameters.

interface Computation<T> {

  public T compute(T n, T m);
}

We can have different implementations of the computation like: IntSum – which returns the sum of two integers, IntDifference – which returns the difference of two integers and IntProduct – which returns the product of two integers.

class IntSum implements Computation<Integer> {

  @Override
  public Integer compute(Integer n, Integer m) {
    return n + m;
  }

}

class IntProduct implements Computation<Integer> {

  @Override
  public Integer compute(Integer n, Integer m) {
    return n * m;
  }
}

class IntDifference implements Computation<Integer> {

  @Override
  public Integer compute(Integer n, Integer m) {
    return n - m;
  }
}

Now lets look at these strategies in action in the below code:

public class AnotherStrategyPattern {

  public static void main(String[] args) {
  
    List<Computation> computations = 
        Arrays.asList(
          new IntSum(), 
          new IntDifference(), 
          new IntProduct()
        );
    
    for (Computation comp : computations) {
      System.out.println(comp.compute(10, 4));
    }
  }
}

The output for the above is:

14
6
40

Strategy Pattern: Another Example with lambda expressions

Now lets look at the same example using Lambda expressions. As in the previous example as well we need not declare classes for different implementation of the strategy i.e the Computation interface, instead we make use of lambda expressions to achieve the same. Lets look at an example:

public class AnotherStrategyPatternWithLambdas {
  public static void main(String[] args) {

    List<Computation<Integer>> computations = 
          Arrays.asList(
              (n, m)-> { return n+m; },
              (n, m)-> { return n*m; },
              (n, m)-> { return n-m; }
          );
    computations.forEach((comp) -> System.out.println(comp.compute(10, 4)));
  }
}

The output for above is:

14
6
40

From the above examples we can see that using Lambda expressions will help in reducing lot of boilerplate code to achieve more concise code. And with practice one can get used to reading lambda expressions.

Creating Internal DSLs in Java, Java 8- Adopting Martin Fowler’s approach

Currently I am reading this wonderful book on DSLs- Domain Specific Languages by Martin Fowler. The buzz around the DSLs, around the languages which support creation of DSLs with ease, the use of DSLs made me curious to know and learn about this concept of DSLs. And the exprience with the book so far has been impressive.

The Definition of DSL as stated by Martin Fowler in his book:

Domain-specific language (noun): a computer programming language of limited expressiveness focused on a particular domain.

DSL is nothing new, its been there for quite a long time. People used XML as a form of DSL. Using XML as a DSL is easy because we have XSD for validation of the DSL, we have parsers for parsing the DSL and we have XSLT for transforming the DSL into other languages. And most of the languages provide a very good support for parsing XMLs and populating their domain model objects. The emergence of languages like Ruby, Groovy and others have increased the adoption of DSL. For example Rails, a web framework written using Ruby, uses DSLs extensively.

In his book Martin Fowler classifies DSLs as Internal, External and Language Workbenches. As I read through the Internal DSL concepts I played around a bit with my own simple DSL using Java as the host language. Internal DSLs reside in the host language and are bound by the syntactic capabilities of the host language. Using Java as the host language didn’t give me really clear DSLs but I made an effort to get it to closer to a form where I could comprehend the DSL comfortably.

I was trying to create a DSL for creating a Graph. As far as I am aware of, the different ways to input and represent a graph are: Adjacency List and Adjacency Matrix. I have always found this difficult to use especially in languages like Java which don’t have matrices as first class citizens. And here I am trying to create an Inner DSL for populating a Graph in Java.

In his book, Martin Fowler stresses the need to keep the Semantic Model different from the DSL and to introduce a intermediate Expression builder which populates the Semantic Model from the DSL. By maintaining this I was able to achieve 3 different forms of the DSLs by writing different DSL syntax and expression builders and all the while using the same semantic model.

Understanding the Semantic Model

The Semantic Model in this case is the Graph class which contains the list of Edge instances and each Edge containing from Vertex, to Vertex and a weight. Lets look at the code for the same:

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

public class Graph {

  private List<Edge> edges;
  private Set<Vertex> vertices;

  public Graph() {
    edges = new ArrayList<>();
    vertices = new TreeSet<>();
  }
  public void addEdge(Edge edge){
    getEdges().add(edge);
  }
  
  public void addVertice(Vertex v){
    getVertices().add(v);
  }

  public List<Edge> getEdges() {
    return edges;
  }

  public Set<Vertex> getVertices() {
    return vertices;
  }
  
  public static void printGraph(Graph g){
    System.out.println("Vertices...");
    for (Vertex v : g.getVertices()) {
      System.out.print(v.getLabel() + " ");
    }
    System.out.println("");
    System.out.println("Edges...");
    for (Edge e : g.getEdges()) {
      System.out.println(e);
    }
  }
}
public class Edge {
  private Vertex fromVertex;
  private Vertex toVertex;
  private Double weight;

  public Edge() {
  }

  public Edge(Vertex fromVertex, Vertex toVertex, Double weight) {
    this.fromVertex = fromVertex;
    this.toVertex = toVertex;
    this.weight = weight;
  }
 
  @Override
  public String toString() {
      return fromVertex.getLabel()+" to "+
             toVertex.getLabel()+" with weight "+ 
             getWeight();
  }

  public Vertex getFromVertex() {
    return fromVertex;
  }

  public void setFromVertex(Vertex fromVertex) {
    this.fromVertex = fromVertex;
  }

  public Vertex getToVertex() {
    return toVertex;
  }

  public void setToVertex(Vertex toVertex) {
    this.toVertex = toVertex;
  }

  public Double getWeight() {
    return weight;
  }

  public void setWeight(Double weight) {
    this.weight = weight;
  }
}
public class Vertex implements Comparable<Vertex> {
  private String label;

  public Vertex(String label) {
    this.label = label.toUpperCase();
  }
  
  @Override
  public int compareTo(Vertex o) {
    return (this.getLabel().compareTo(o.getLabel()));
  }

  public String getLabel() {
    return label;
  }

  public void setLabel(String label) {
    this.label = label;
  }
}

Now that we have the Semantic Model in place, lets build the DLSs. You should notice that I am not going to change my Semantic model. Its not a hard and fast rule that the semantic model shouldn’t change, instead the semantic model can evolve by adding new APIs for fetching the data or modifying the data. But binding the Semantic model tightly to the DSL will not be a good approach. Keeping them separate helps in testing the Semantic Model and the DSL independently.

The different approaches for creating Internal DSLs stated by Martin Fowler are:

I have illustrated 3 in this post except Functional Sequence. But I have used Functional Sequence approach while using the Closures/Lambda expression.

Inner DSL by Method Chaining

I am envisaging my DSL to be something like:

Graph()
  .edge()
    .from("a")
    .to("b")
    .weight(12.3)
  .edge()
    .from("b")
    .to("c")
    .weight(10.5)

To enable the creation of such DSL we would have to write an expression builder which allows popuplation of the semantic model and provides a fluent interface enabling creation of the DSL.

I have created 2 expressions builders- One to build the complete Graph and the other to build individual edges. All the while the Graph/Edge are being built, these expression builders hold the intermediate Graph/Edge objects. The above syntax can be achieved by creating static method in these expression builders and then using static imports to use them in the DSL.

The Graph() starts populating the Graph model while the edge() and series of methods later namely: from(), to(), weight() populate the Edge model. The edge() also populates the Graph model.

Lets look at the GraphBuilder which is the expression builder for populating the Graph model.

public class GraphBuilder {
    
  private Graph graph;

  public GraphBuilder() {
    graph = new Graph();
  }
  
  //Start the Graph DSL with this method.
  public static GraphBuilder Graph(){
    return new GraphBuilder();
  }
  
  //Start the edge building with this method.
  public EdgeBuilder edge(){
    EdgeBuilder builder = new EdgeBuilder(this);
 
    getGraph().addEdge(builder.edge);
    
    return builder;
  }
  
  public Graph getGraph() {
    return graph;
  }
 
  public void printGraph(){
    Graph.printGraph(graph);
  }
}

And the EdgeBuilder which is the expression builder for populating the Edge model.

public class EdgeBuilder {
  
  Edge edge;
  
  //Keep a back reference to the Graph Builder.
  GraphBuilder gBuilder;
  
  public EdgeBuilder(GraphBuilder gBuilder) {
    this.gBuilder = gBuilder;
    edge = new Edge();
  }
  
  public EdgeBuilder from(String lbl){
    Vertex v = new Vertex(lbl);
    edge.setFromVertex(v);
    gBuilder.getGraph().addVertice(v);
    return this;
  }
  public EdgeBuilder to(String lbl){
    Vertex v = new Vertex(lbl);
    edge.setToVertex(v);
    gBuilder.getGraph().addVertice(v);
    return this;
  }
  
  public GraphBuilder weight(Double d){
    edge.setWeight(d);
    return gBuilder;
  }
  
}

Lets try and experiment the DSL:

public class GraphDslSample {

  public static void main(String[] args) {

    Graph()
      .edge()
        .from("a")
        .to("b")
        .weight(40.0)
      .edge()
        .from("b")
        .to("c")
        .weight(20.0)
      .edge()
        .from("d")
        .to("e")
        .weight(50.5)
      .printGraph();

    Graph()
      .edge()
        .from("w")
        .to("y")
        .weight(23.0)
      .edge()
        .from("d")
        .to("e")
        .weight(34.5)
      .edge()
        .from("e")
        .to("y")
        .weight(50.5)
      .printGraph();

  }
}

And the output would be:

Vertices...
A B C D E 
Edges...
A to B with weight 40.0
B to C with weight 20.0
D to E with weight 50.5
Vertices...
D E W Y 
Edges...
W to Y with weight 23.0
D to E with weight 34.5
E to Y with weight 50.5

Do you not find this approach more easy to read and understand than the Adjacency List/Adjacency Matrix approach? This Method Chaining is similar to Train Wreck pattern which I had written about sometime back.

Inner DSL by Nested Functions

In the Nested functions approach the style of the DSL is different. In this approach I would nest functions within functions to populate my semantic model. Something like:

Graph(
  edge(from("a"), to("b"), weight(12.3),
  edge(from("b"), to("c"), weight(10.5)
);

The advantage with this approach is that its heirarchical naturally unlike method chaining where I had to format the code in a different way. And this approach doesn’t maintain any intermediate state within the Expression builders i.e the expression builders don’t hold the Graph and Edge objects while the DSL is being parsed/executed. The semantic model remain the same as discussed here.

Lets look at the expression builders for this DSL.

//Populates the Graph model.
public class NestedGraphBuilder {
 
  public static Graph Graph(Edge... edges){
    Graph g = new Graph();
    for(Edge e : edges){
      g.addEdge(e);
      g.addVertice(e.getFromVertex());
      g.addVertice(e.getToVertex());
    }
    return g;
  }
  
}
//Populates the Edge model.
public class NestedEdgeBuilder {
    
  public static Edge edge(Vertex from, Vertex to, 
                          Double weight){
    return new Edge(from, to, weight);
  }
  
  public static Double weight(Double value){
    return value;
  }
    
}
//Populates the Vertex model.
public class NestedVertexBuilder {
  public static Vertex from(String lbl){
    return new Vertex(lbl);
  }
  
  public static Vertex to(String lbl){
    return new Vertex(lbl);
  }
}

If you have observed all the methods in the expression builders defined above are static. We use static imports in our code to create a DSL we started to build.

Note: I have used different packages for expression builders, semantic model and the dsl. So please update the imports according to the package names you have used.

//Update this according to the package name of your builder
import static nestedfunction.NestedEdgeBuilder.*;
import static nestedfunction.NestedGraphBuilder.*;
import static nestedfunction.NestedVertexBuilder.*;

/**
 *
 * @author msanaull
 */
public class NestedGraphDsl {

  public static void main(String[] args) {
    Graph.printGraph(
      Graph(
        edge(from("a"), to("b"), weight(23.4)),
        edge(from("b"), to("c"), weight(56.7)),
        edge(from("d"), to("e"), weight(10.4)),
        edge(from("e"), to("a"), weight(45.9))
      )
    );
    
  }
}

And the output for this would be:

Vertices...
A B C D E 
Edges...
A to B with weight 23.4
B to C with weight 56.7
D to E with weight 10.4
E to A with weight 45.9

Now comes the interesting part: How can we leverage the upcoming lambda expressions support in our DSL.

Inner DSL using Lambda Expression

If you are wondering what Lambda expressions are doing in Java, then please spend some time here before proceeding further.

In this example as well we will stick with the same semantic model described here. This DSL leverages Function Sequence along with using the lambda expression support. Lets see how we want our final DSL to be like:

Graph(g -> {
    g.edge( e -> {
      e.from("a");
      e.to("b");
      e.weight(12.3);
    });
    
    g.edge( e -> {
      e.from("b");
      e.to("c");
      e.weight(10.5);
    });
    
  }
)

Yeah I know the above DSL is overloaded with punctuations, but we have to live with it. If you dont like it, then may be pick a different language.

In this approach our expression builders should accept lambda expression/closure/block and then populate the semantic model by executing the lambda expression/closure/block. The expression builder in this implementation maintain the intermediate state of the Graph and Edge objects in the same way we did in DSL implementation by Method Chaining.

Lets look at our expression builders:

//Populates the Graph model.
public class GraphBuilder {

  Graph g;
  public GraphBuilder() {
    g = new Graph();
  }
  
  public static Graph Graph(Consumer<GraphBuilder> gConsumer){
    GraphBuilder gBuilder = new GraphBuilder();
    gConsumer.accept(gBuilder);
    return gBuilder.g;
  }
  
  public void edge(Consumer<EdgeBuilder> eConsumer){
    EdgeBuilder eBuilder = new EdgeBuilder();
    eConsumer.accept(eBuilder);
    Edge e = eBuilder.edge();
    g.addEdge(e);
    g.addVertice(e.getFromVertex());
    g.addVertice(e.getToVertex());
  }
}
//Populates the Edge model.
public class EdgeBuilder {
  private Edge e;
  public EdgeBuilder() {
    e = new Edge();
  }
  
  public Edge edge(){
    return e;
  }

  public void from(String lbl){
    e.setFromVertex(new Vertex(lbl));
  }
  public void to(String lbl){
    e.setToVertex(new Vertex(lbl));
  }
  public void weight(Double w){
    e.setWeight(w);
  }
  
}

In the GraphBuilder you see two higlighted lines of code. These make use of a functional interface, Consumer, to be introduced in Java 8.

Now lets make use of the above expression builders to create our DSL:

//Update the package names with the ones you have given
import graph.Graph;
import static builder.GraphBuilder.*;

public class LambdaDslDemo {
  public static void main(String[] args) {
    Graph g1 = Graph( g -> {
      g.edge( e -> {
        e.from("a");
        e.to("b");
        e.weight(12.4);
      });
      
      g.edge( e -> {
        e.from("c");
        e.to("d");
        e.weight(13.4);
      });
    });
    
    Graph.printGraph(g1);
  }
}

And the output is:

Vertices...
A B C D 
Edges...
A to B with weight 12.4
C to D with weight 13.4

With this I end this code heavy post. Let me know if you want me to spit this into 3 posts- one for each DSL implementation. I kept it in one place so that it would help us in comparing the 3 different approaches.

To summarise:

Factory Method pattern in Java

In my previous post about the Template Method pattern, I showed how one can leverage lambda expression and default methods. In this post I will explore about factory method pattern and see how one can leverage method references, another feature added in Java 8 alongside lambda expressions.

Lets consider a Vehicle interface and 2 of its implementations namely Car and Vehicle.

interface Vehicle{
  public void drive();
  public void clean();
}
class Car implements Vehicle{
  @Override
  public void drive(){
    System.out.println("Driving a car...");
  }
  
  @Override
  public void clean(){
    System.out.println("Cleaning a car...");
  }
}
class Bus implements Vehicle{
  @Override
  public void drive(){
    System.out.println("Driving a Bus...");
  }
  
  @Override
  public void clean(){
    System.out.println("Cleaning a Bus...");
  }
}

And to drive() and clean() the Vehicle we would use a VehicleDriver.

Implementation in Java 7 and before

Lets consider the implementation and of VehicleDriver from a Pre Java 8 point of view i.e Java 7 and before.

abstract class VehicleDriver{
  public abstract Vehicle getVehicle();
  public void driveVehicle(){
    getVehicle().drive();
  }
  public void cleanVehicle(){
    getVehicle().clean();
  }
}
class CarDriver extends VehicleDriver{
  @Override
  public Vehicle getVehicle(){
    return new Car();
  }
}

class BusDriver extends VehicleDriver{
  @Override
  public Vehicle getVehicle(){
    return new Bus();
  }
}

In the above VehicleDriver implementation the getVehicle() method is the factory method which is overridden by the CarDriver and Busdriver to return Car and Bus instances respectively. In this way the programmer would be more concerned about using the VehicleDriver abstraction and need not be concerned about its different implementations. There’s another related pattern: Factory Pattern which is slightly different from this pattern and readers should not confuse this with that pattern. Ok, lets quickly look at how this can be used before proceeding to its Java 8 variant:

public class FactoryMethodPattern {
   public static void main(String[] args) {
    
    handleVehicle(new CarDriver());
    handleVehicle(new BusDriver());
  }
  static void handleVehicle(VehicleDriver2 vDriver){
    System.out.println("Handling a new vehicle. Pre lambda way");
    vDriver.driveVehicle();
    vDriver.cleanVehicle();
  }
}

The output would be:

Handling a new vehicle. Pre lambda way
Driving a car...
Cleaning a car...
Handling a new vehicle. Pre lambda way
Driving a Bus...
Cleaning a Bus...

Leveraging Java 8

Firstly we dont need an abstract VehicleDriver and its 2 different implementation. Instead we make use of Interfaces with Default methods to create the VehicleDriver abstraction as shown below:

interface VehicleDriver{
    public Vehicle getVehicle();
    public default void driveVehicle(){
        getVehicle().drive();
    }
    public default void cleanVehicle(){
        getVehicle().clean();
    }   
}

Now lets come to the interesting part- Using Method references instead of creating different implementation of the VehicleDriver. These method references provide a way for the code to get the required instance of Car or Bus class without going into the hassles of overriding the getVehicle() method. Confused? Curious? Lets look at how we can achieve that:

public class FactoryMethodPatternLambda {
  public static void main(String[] args) {

    handleVehicle(Car::new);
    handleVehicle(Bus::new);
  }
  static void handleVehicle(VehicleDriver vDriver){
    System.out.println("Handling a new vehicle...");
    vDriver.driveVehicle();
    vDriver.cleanVehicle();
  }
}

And the output for this would be:

Handling a new vehicle...
Driving a car...
Cleaning a car...
Handling a new vehicle...
Driving a Bus...
Cleaning a Bus...

We just provided the handleVehicle method a Vehicle to handle and didn’t worry about how its being handled or who’s handling it. But in the Java 7 and before implementation we had to be aware that there is some VehicleDriver abstract class and then we had to override its some method and then create instance of that extended class. My main intention by showing this example is that one can leverage Java 8 features to create cleaner and easy to use APIs. But with all new features comes the learning curve.

Note: In both the above implementations the common part is the Vehicle, Car, Bus classes which are used by both Java 7 and Java 8 implementations.

Train Wreck Pattern – A much improved implementation in Java 8

Venkat Subramaniam at a talk today mentioned about Cascade Method pattern or Train Wreck pattern which looks something like: someObject.method1().method2().method3().finalResult()

Few might associate this with the builder pattern, but its not the same. Anyways lets have a look at an example for this in Java with out the use of lambda expression:

public class TrainWreckPattern {
  public static void main(String[] args) {
    new Mailer()
    .to("to@example.com")
    .from("from@exmaple.com")
    .subject("Some subject")
    .body("Some content")
    .send();
    
  }
}

class Mailer{
  public Mailer to(String address){ 
    System.out.println("To: "+address); 
    return this;
  }
  public Mailer from(String address){ 
    System.out.println("From: "+address); 
    return this;
  }
  public Mailer subject(String sub){ 
    System.out.println("Subject: "+sub); 
    return this;
  }
  public Mailer body(String body){ 
    System.out.println("Body: "+body); 
    return this;
  }
  public void send(){ 
    System.out.println("Sending ..."); 
  }
}

I have taken the same example which Venkat Subramaniam took in his talk. In the above code I have a Mailer class which accepts a series of values namely: to, from, subject and a body and then sends the mail. Pretty simple right? But there is some problem associated with this: One doesn’t know what to do with the Mailer object once it has finished sending the mail. Can it be reused to send another mail? Or should it be held to know the status of email sent? This is not known from the code above and lot of times one cannot find this information in the documentation. What if we can restrict the scope of the Mailer object within some block so that one cannot use it once its finished its operation?

Java 8 provides an excellent mechanism to achieve this using Lambda expressions. lets look at how it can be done:

public class TrainWreckPatternLambda {

  public static void main(String[] args) {
    Mailer.send( mailer -> {
      mailer.to("to@example.com")
            .from("from@exmaple.com")
            .subject("Some subject")
            .body("Some content");
    });
  }

}

class Mailer{

  private Mailer(){
    
  }
  public Mailer to(String address){ 
    System.out.println("To: "+address); 
    return this;
  }
  public Mailer from(String address){ 
    System.out.println("From: "+address); 
    return this;
  }
  public Mailer subject(String sub){ 
    System.out.println("Subject: "+sub); 
    return this;
  }
  public Mailer body(String body){ 
    System.out.println("Body: "+body); 
    return this;
  }
  public static void send(Consumer<Mailer> mailerOperator){ 
    Mailer mailer = new Mailer();
    mailerOperator.accept(mailer);
    System.out.println("Sending ..."); 
  }
}

In the above implementation I have restricted the instantiation of the Mailer class to the send() method by making the constructor private. And then the send() method now accepts an implementation of Consumer interface which is a Single Abstract method class and can be represented by a Lambda expression. And in the main() method I pass a lambda expression which accepts a Mailer instance and then configures the mailer object before being used in the send() method.

The use of lambda expression has created a clear boundary for the use of the Mailer object and this way its much ore clearer for someone reading the code as to how the Mailer object has to be used.

Let me know if there is something more that I can improve in this example I have shared.

Converting a List into comma separated value string in Java

We all have at least once in our coding life time done this: “Concatenate the elements of a List into a comma separated string”. And each time we have spent some time figuring out how to do it or sometimes we copy the code from a previous implementation. Lets see how we can implement this scenario:

public class ListToCommaValues {

  public static void main(String[] args) {
  
    //List of numbers we want to concatenate
    List<Integer> numbers = Arrays.asList(1,2,3,4,5,6,7);

    //The string builder used to construct the string
    StringBuilder commaSepValueBuilder = new StringBuilder();

    //Looping through the list
    for ( int i = 0; i< numbers.size(); i++){
      //append the value into the builder
      commaSepValueBuilder.append(numbers.get(i));
      
      //if the value is not the last element of the list
      //then append the comma(,) as well
      if ( i != numbers.size()-1){
        commaSepValueBuilder.append(", ");
      }
    }
    System.out.println(commaSepValueBuilder.toString());

  }

}

the output would be: 1, 2, 3, 4, 5, 6, 7. Its not rocket science, but just too much verbose and clumsy to write.

You all must be wondering the purpose of writing this article or taking up this scenario. At the Great Indian Developer Conference today Venkat Subramaniam was giving a talk on Design patterns in Modern JVM languages (Groovy, Scala) and mentioned about this scenario and also showed some code in Scala, Groovy and he also mentioned about Java 8. And bang I got an idea to blog about this and here is the same in front of you all.

Lets see how the same can be done in Java 8:

//Java 8 way to concatenate the list of numbers
public class ListToCommaValuesJava8 {

  public static void main(String[] args) {
  
    List<Integer> numbers = Arrays.asList(1,2,3,4,5,6,7);
    
    System.out.println(numbers.stream()
        .map(number -> String.valueOf(number))
        .collect(toStringJoiner(", ")));
  }
}

And the output again would be: 1, 2, 3, 4, 5, 6, 7. The above code is less verbose and much easier to read than the one shown in the beginning. If you are left wondering about stream(), collect() I would recommend you to read a similar and more detailed post using the same.

Let me explain the above single line of code:
map() – Takes in a lambda expression which accepts an argument and returns some value(this is an implementation of java.util.Function interface). In the example above the lambda expression accepts an integer and converts it into a string.

toStringJoiner() – It is a static method in Collectors class and returns a Collector which embeds the logic to use the elements of the stream and combine them into a new StringJoiner instance using the separator passed to the Collector.

StringJoiner- From the Javadoc: StringJoiner is used to construct a sequence of characters separated by an infix delimiter and optionally starting with a supplied prefix and ending with a supplied suffix. In the above example we are making use of the infix delimiter.

A simple application of Lambda Expressions in Java 8

I have been trying to fit in lambda expressions in the code I write and this simple example is a consequence of the same. For those totally unaware of Lambda Expressions in Java, I would recommend them to read this first before getting into this post.

Ok, now that you are familiar with Lambda Expressions (after reading the introductory post), lets go in the simple example which I thought of as a good use of lambda expression.

Consider this scenario:

A certain operation is surrounded by some pre-processing and some post-processing. And the operation to be executed can vary depending on the behaviour expected. The pre-processing code extracts the required parameters for the operation and the post-processing does the necessary cleanup.

Lets us see how this can be done with the use of Interfaces and their implementations via Anonymous Inner classes.

Using anonymous inner classes

An interface which has to be implemented to provide the required behavior:

interface OldPerformer {
  public void performTask(String id, int status);
}

And lets look at method which performs the pre-processing, executes the required operation and then the post-processing:

public class PrePostDemo {
  static void performTask(String id, OldPerformer performer) {
    System.out.println("Pre-Processing...");
    System.out.println("Fetching the status for id: " + id);
    int status = 3;//Some status value fetched
    performer.performTask(id, status);
    System.out.println("Post-processing...");
  }
}

We need to pass 2 things- an identifier to perform the pre-processing and an implementation of the operation, which can be done as shown below:

public class PrePostDemo {
  public static void main(String[] args) {
    //has to be declared final to be accessed within
    //the anonymous inner class.
    final String outsideOfImpl = "Common Value";
    performTask("1234", new OldPerformer() {
      @Override
      public void performTask(String id, int status) {
        System.out.println("Finding data based on id...");
        System.out.println(outsideOfImpl);
        System.out.println("Asserting that the status matches");
      }
    });
    performTask("4567", new OldPerformer() {
      @Override
      public void performTask(String id, int status) {
        System.out.println("Finding data based on id...");
        System.out.println(outsideOfImpl);
        System.out.println("Update status of the data found");
      }
    });
  }
}

As seen above, the variables declared outside of the Anonymous inner class have to be declared as final for them to be accessible in the methods of the anonymous inner class. The output of the above code would be:

Pre-Processing...
Fetching the status for id: 1234
Finding data based on id...
Common Value
Asserting that the status matches
Post-processing...
Pre-Processing...
Fetching the status for id: 4567
Finding data based on id...
Common Value
Update the status of the data found
Post-processing...

Using Lambda expression

Lets look at how the above can be written using the lambda expression:

public class PrePostLambdaDemo {
  public static void main(String[] args) {    
    //Need not be declared as final for use within a 
    //lambda expression, but has to be eventually final.
    String outsideOfImpl = "Common Value";

    doSomeProcessing("123", (String id, int status) -> {
      System.out.println("Finding some data based on"+id);
      System.out.println(outsideOfImpl);
      System.out.println("Assert that the status is "+status );
    });

    doSomeProcessing("456", (String id, int status) -> {
      System.out.print("Finding data based on id: "+id);
      System.out.println(outsideOfImpl);
      System.out.println("And updating the status: "+status);
    });
  }
    
  static void doSomeProcessing(String id, Performer performer ){
    System.out.println("Pre-Processing...");
    System.out.println("Finding status for given id: "+id);
    int status = 2;
    performer.performTask(id, status);
    System.out.println("Post-processing...");
  }
}

interface Performer{
public void performTask(String id, int status);
}

Apart from the interesting lambda expression syntax, the variable outside the scope of the lambda expression is not declared as final. But it has to be eventually final, which means that the value of the variable: outsideOfImpl shouldn’t be modified once declared.

This is just another cleaner way of using lambda expression in place of Anonymous inner classes.

A parting note: The schedule release of JDK 8 has been pushed further into Feb 2014 and the complete schedule can be found here. I am using the Project lambda build which keeps getting updated each day, so feel free to let me know if something of this doesn’t work on latest builds. I will try my best to keep updating the builds and trying out the samples posted here.

Another note: Dont get overwhelmed by whats happening in Java 8, these features are already part of lot of programming languages now. I found that learning the syntax and approach of lambda expressions in Java has helped me to understand and think functionally and more specifically appreciate Scala closures.

Template Method Pattern- Using Lambda Expressions, Default Methods

Template Method pattern is one of the 23 design patterns explained in the famous Design Patterns book by Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides. The intent of this pattern is stated as:

Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. TemplateMethod lets subclasses redefine certain steps of an algorithm without changing the algorithm’s structure.

To explain in simple terms, consider the following scenario: Assume there is a workflow system in which 4 tasks have to be performed in the given order so as to successfully complete the workflow. Some of the tasks out of the 4 tasks can be customised by different workflow system implementation.

Template Method pattern can be applied to above scenario by encapsulating the workflow system into an abstract class with few of the tasks out of the 4 tasks implemented. And leave the implementation of remaining tasks to the subclasses of the abstract class.

So the above when implemented:

/**
 * Abstract Workflow system
 */
abstract class WorkflowManager2{
  public void doTask1(){
    System.out.println("Doing Task1...");
  }

  public abstract void doTask2();

  public abstract void doTask3();

  public void doTask4(){
    System.out.println("Doing Task4...");
  }
}

/**
 * One of the extensions of the abstract workflow system
 */
class WorkflowManager2Impl1 extends WorkflowManager2{
  @Override
  public void doTask2(){
    System.out.println("Doing Task2.1...");
  }

  @Override 
  public void doTask3(){
    System.out.println("Doing Task3.1...");
  }
}

/**
 * Other extension of the abstract workflow system
 */
class WorkflowManager2Impl2 extends WorkflowManager2{
  @Override
  public void doTask2(){
    System.out.println("Doing Task2.2...");
  }

  @Override 
  public void doTask3(){
    System.out.println("Doing Task3.2...");
  }
}

Let me just go ahead and show how these workflow implementations are used:

public class TemplateMethodPattern {
  public static void main(String[] args) {
   initiateWorkFlow(new WorkflowManager2Impl1());
   initiateWorkFlow(new WorkflowManager2Impl2());
  }

  static void initiateWorkFlow(WorkflowManager2 workflowMgr){
    System.out.println("Starting the workflow ... the old way");
    workflowMgr.doTask1();
    workflowMgr.doTask2();
    workflowMgr.doTask3();
    workflowMgr.doTask4();
  }
}

and the output would be..

Starting the workflow ... the old way
Doing Task1...
Doing Task2.1...
Doing Task3.1...
Doing Task4...
Starting the workflow ... the old way
Doing Task1...
Doing Task2.2...
Doing Task3.2...
Doing Task4...

So far so good. But the main intent of this post is not to create yet another blog post on Template Method pattern, but to see how we can leverage Java 8 Lambda Expression and Default Methods. I have already written before, that only interfaces which have Single Abstract Methods can be written as lambda expressions. What this translates to in this example is that, the WorkflowManager2 can only have one abstract/customizable task out of the 4 tasks.

So restricting to one abstract method is a major restriction and may not be applicable in many realtime scenarios. I dont wish to reiterate the same old Template Method pattern examples, instead my main intention of writing this is to show how lambda expressions and default methods can be leveraged in scenarios where you are dealing with abstract classes with single abstract methods.

If you are left wondering what these lambda expressions in java mean and also these default methods in java, then please spend some time to read about lambda expressions and default methods before proceeding further.

Instead of an abstract class we would use an interface with default methods, so our workflow system would look like:

interface WorkflowManager{
  public default void doTask1(){
    System.out.println("Doing Task1...");
  }

  public void doTask2();

  public default void doTask3(){
    System.out.println("Doing Task3...");
  }

  public default void doTask4(){
    System.out.println("Doing Task4...");
  }
}

Now that we have the workflow system with customisable Task2, we will go ahead and initiate some customised workflows using Lambda expressions…

public class TemplateMethodPatternLambda {
  public static void main(String[] args) {
    /**
     * Using lambda expression to create different 
     * implementation of the abstract workflow
     */
    initiateWorkFlow(()->System.out.println("Doing Task2.1..."));
    initiateWorkFlow(()->System.out.println("Doing Task2.2..."));
    initiateWorkFlow(()->System.out.println("Doing Task2.3..."));
  }

  static void initiateWorkFlow(WorkflowManager workflowMgr){
    System.out.println("Starting the workflow ...");
    workflowMgr.doTask1();
    workflowMgr.doTask2();
    workflowMgr.doTask3();
    workflowMgr.doTask4();
  }
}

This is in a small way lambda expressions can be leveraged in the Template Method Pattern

Arrays.sort versus Arrays.parallelSort

We all have used Arrays.sort to sort objects and primitive arrays. This API used merge sort OR Tim Sort underneath to sort the contents as shown below:

public static void sort(Object[] a) {
  if (LegacyMergeSort.userRequested)
    legacyMergeSort(a);
  else
    ComparableTimSort.sort(a);
}

This is all done sequentially, even though merge sort uses divide and conquer technique, its all done sequentially.

Come Java 8, there is a new API introduced for sorting which is Arrays#parallelSort. This is does the sorting in parallel. Interesting right! Lets see how it does…

Arrays#parallelSort uses Fork/Join framework introduced in Java 7 to assign the sorting tasks to multiple threads available in the thread pool. This is called eating your own dog food. Fork/Join implements a work stealing algorithm where in a idle thread can steal tasks queued up in another thread.

An overview of Arrays#parallelSort:

The method uses a threshold value and any array of size lesser than the threshold value is sorted using the Arrays#sort() API (i.e sequential sorting). And the threshold is calculated considering the parallelism of the machine, size of the array and is calculated as:

private static final int getSplitThreshold(int n) {
  int p = ForkJoinPool.getCommonPoolParallelism();
  int t = (p > 1) ? (1 + n / (p << 3)) : n;
  return t < MIN_ARRAY_SORT_GRAN ? MIN_ARRAY_SORT_GRAN : t;
}

Once its decided whether to sort the array in parallel or in serial, its now to decide how to divide the array in to multiple parts and then assign each part to a Fork/Join task which will take care of sorting it and then another Fork/Join task which will take care of merging the sorted arrays. The implementation in JDK 8 uses this approach:
– Divide the array into 4 parts.
– Sort the first two parts and then merge them.
– Sort the next two parts and then merge them.
And the above steps are repeated recursively with each part until the size of the part to sort is not lesser than the threshold value calculated above.

Some interesting results:

I tried to compare the time taken by the Arrays#sort and Arrays#parallelSort on a machine with 4 CPUs. The program which I used for this comparison is:

public class ArraysParallelDemo {
  public static void main(String[] args) throws FileNotFoundException {
    List<Double> arraySource = new ArrayList<>();
    
    Scanner reader = new Scanner(ClassLoader.
        getSystemResourceAsStream("java8demo/large_array_input"));
    while(reader.hasNext()){
      String line = reader.nextLine();
      String[] strNums = line.split(",");
      for ( String strN : strNums){
          arraySource.add(Double.parseDouble(strN));
      }
    }
    
    System.out.println(arraySource.size());
    
    Double [] myArray = new Double[1];
    myArray = arraySource.toArray(myArray);
    long startTime = System.currentTimeMillis();
    Arrays.sort(myArray);
    long endTime = System.currentTimeMillis();
    System.out.println("Time take in serial: "+
        (endTime-startTime)/1000.0);
    
    Double [] myArray2 = new Double[1];
    myArray2 = arraySource.toArray(myArray);
    startTime = System.currentTimeMillis();
    Arrays.parallelSort(myArray2);
    endTime = System.currentTimeMillis();
    System.out.println("Time take in parallel: "+
        (endTime-startTime)/1000.0);
      
  }
}

And the time taken by each of the APIs against arrays of double values of different sizes is shown below:
Table_ParallelSort2
Graph_ParallelSort2

There is a similar implementation for Lists as well and lot of the operations on Lists have a parallel equivalent.

Supplier interface in java.util.function package in Java 8

In my previous posts I wrote about Predicate, Consumer and Function interfaces. In this post I will write about Supplier interface with which I will conclude the description of the interfaces in the java.util.function package. Though there are many other interfaces in that package, but the interfaces I have explained form the crux of the other interfaces.

The javadoc for Supplier interface states:

A supplier of objects. The result objects are either created during the invocation of get() or by some prior action.

And the sole method in this interface is get() which should return an object of the declared type.

To understand the usage of this interface, lets consider 2 classes- Vehicle and Car defined as:

class Vehicle{
  public void drive(){ 
    System.out.println("Driving vehicle ...");
  }
}
class Car extends Vehicle{
  @Override
  public void drive(){
    System.out.println("Driving car...");
  }
}

And lets consider a static method which invokes the drive() method on the instance of Vehicle or Car:

public class SupplierDemo {   
  static void driveVehicle(Supplier<? extends Vehicle> supplier){
    Vehicle vehicle = supplier.get();
    vehicle.drive();   
  }
}

And to invoke the above driveVehicle method, we should provide an implementation of the Supplier interface which we can do by passing in a lambda expression. Lets look at the code:

public static void main(String[] args) {
  //Using Lambda expression
  driveVehicle(()-> new Vehicle());
  driveVehicle(()-> new Car());
  
  //Using method expression
  driveVehicle(Vehicle::new);
  driveVehicle(Car::new);
}

The first two invocations are familiar to the readers of my blog, but the other two are something new and those are called as “Method Expression“. Soon I will write about method expression but if you are curious to know about it, you can read about it here under the section: “8. Method Expression“.