Decorator Pattern using Java 8

In this post we are going to look at a couple of examples which use the GoF Decorator pattern. We will then refactor this code to use some of the features introduced in Java 8 which give Java a taste of functional programming. After this refactoring, we will see if the refactored code showcasing the decorator pattern becomes concise and easy to understand or makes it more complicated.

The basic idea behind the decorator pattern is that it allows us to add behavior to an object without affecting or modifying the interface of the class. I would suggest you to read and get a basic idea about the Decorator pattern in case you are completely unaware of it.

I would be considering 2 existing posts showcasing the decorator pattern and then we would be refactoring the code using Java 8.

Typical Decorator – Example one

The first example that we are going to look at is a code sample that I saw from a site, codeofdoom.com, which unfortunately does not exist anymore(domain seems to have expired). That post referred to an example which was simple to read and showed how a typical decorator pattern is implemented. I thought I had understood the pattern but I was mistaken.

The requirement in that example

The requirement that I understood from the code – We need to format a particular text supplied as input. The formatting can be one of several options- we return the text as it is, format the text to upper case, replace a word in the text with another word , concatenation of text with another string or a permutation and combination of the options. I have stated the requirements upfront but usually as developers we are never aware of the requirements upfront and requirements always keep changing. It would not make sense to create separate classes for each permutation – combination. In such situations, the decorator pattern can be extremely useful.

The example mentioned has an interface Text and a basic implementation of the same which returns the text. There are 3 classes AllCaps, StringConcat and ReplaceThisWithThat which are decorators taking the input text and adding specific behavior to it. The advantage of using the decorator pattern here is that we can use and combine 1 or more decorators to achieve formatting of the input text dynamically rather than sub-classing and creating different combinations of the sub-classes.However the implementation of a typical decorator is not so straightforward to understand. I had to debug a little bit to get a good understanding of how the code really decorates the object.

So let’s define an interface Text with a method format as shown below –

public interface Text {
    public String format(String s);
}

The BaseText class simply returns the text as is –

public class BaseText implements Text{

    public String format(String s){
        return s;
    }
}

The TextDecorator class serves as base decorator class which other classes extend. This decorator class is like a core class which helps in combining different functionalities.

public abstract class TextDecorator implements Text {

    private Text text;

    public TextDecorator(Text text) {
        this.text = text;
    }

    public abstract String format(String s);
}

The AllCaps class takes the input and formats it to uppercase –

public class AllCaps extends TextDecorator{

    public AllCaps(Text text){
        super(text);
    }

    public String format(String s){
        return text.format(s).toUpperCase();
    }
}

The StringConcat class calls format and then concatenates the input string –

public class StringConcat extends TextDecorator{

    public StringConcat(Text text){
        super(text);
    }

    public String format(String s){
        return text.format(s).concat(s);
    }
}

And finally, the class which replaces text “this” with “that” –

public class ReplaceThisWithThat extends TextDecorator{

    public ReplaceThisWithThat(Text text){
        super(text);
    }

    public String format(String s){
        return text.format(s).replaceAll("this","that");
    }
}

Test class to run the decorators –

public class TextDecoratorRunner{

    public static void main(String args[]){

        Text baseText = new BaseText();
                
        Text t = new ReplaceThisWithThat(new StringConcat(new AllCaps(baseText)) );

        System.out.println(t.format("this is some random text"));
    }
}

Notice how the call is done. It is actually inside-out but the code is read from the outside-in.

A pixel is worth 1024 bits
Flow of the Decorator pattern

The left hand side shows the calls to the format method in each decorator class and the right hand side shows how the decorators hold references or how they are chained.

The final output from this is – THIS IS SOME RANDOM TEXTthat is some random text.

Refactoring the decorator pattern using Java 8

Well, now to the main task of re-implementing the same using functional style. The BaseText class shown above has a function, format, which simply takes a String and returns a String. This can be represented using functional interface, Function<String,String> – introduced in Java 8.

import java.util.function.Function;

public class BaseText implements Function<String,String>{

    public BaseText(){
    }

    @Override
    public String apply(String t) {
        return t;
    }
}

Now, each decorator class implements a simple functionality of formatting a string in different ways and can be combined as shown below in a single class using static methods.

public class TextDecorators
{

    public static String allCaps(String s){
        return s.toUpperCase();
    }

    public static String concat(String input) {
        return input.concat("this is some random text");
    }

    public static String thisWithWhat(String input) {
        return input.replaceAll("this", "that");
    }

}

This simply leads us to the following –

public class TextDecoratorRunner {

    public static void main(String[] args) {
        String finalString = new BaseText()
                .andThen(TextDecorators::allCaps)
                .andThen(TextDecorators::concat)
                .andThen(TextDecorators::thisWithWhat)
                .apply("this is some random text");

        System.out.println(finalString);
    }
}

The code above does function chaining and uses method reference. It takes the text and passes it through a chain of functions which act as decorators. Each function applies a decoration and passes the decorated string as output to the next function which treats it as an input.  In this scenario, there is no need to have separate classes which act as decorators or the abstract base class. This implementation offers the same flexibility as the typical solution but I think it is also much much easier to understand as compared to the typical way of implementing the decorator pattern. There is also no inside-out or outside-in business when we call the function.

Typical Decorator – Example two

The second example that we are going to consider is shown here groovy decorator.  I would suggest you to read it to get a basic understanding of the use case. Also note the confusion between whether the complete text is logged in upper case or timestamp is logged in lower case.

Decorator pattern refactored

Let us try and use the same concept of function chaining to refactor this.

First the interface would like this –

public interface Logger {
	public void log(String message);
}

The SimpleLogger class –

public class SimpleLogger implements Logger {

	@Override
	public void log(String message) {
		System.out.println(message);

	}
}

The individual decorated logger can be represented as below –

import java.util.Calendar;

public class Loggers {
	
	public static String withTimeStamp(String message){
		
		Calendar now = Calendar.getInstance(); 
		return now.getTime() + ": "+  message;
	}
	
	public static String uppperCase(String message){
		
		return message.toUpperCase();
	}
}

And finally using function chaining –

import java.util.function.Function;
import java.util.stream.Stream;

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

Logger logger = new SimpleLogger();

        Function<String,String> decorators = Stream.<Function<String,String>>of(Loggers::withTimeStamp,Loggers::uppperCase)
                .reduce(Function.identity(),Function::andThen);

        logger.log(decorators.apply("G'day Mate"));

	}
}

The code above looks a little daunting at first glance but it is actually simple, let us break it down –

Lines 9- 12 are the key to understanding this. I am using Stream.of and passing method references which are individual decorators.

  1. To combine them or to chain them, we use the Stream.of. The Function<String,String> in Stream.<Function<String,String>>of  is more of a compilation thing , to represent the Stream that the output is a Function<String,String>.  Using the Stream.of, we are forming a chain of functions.
  2. Now to the reduce part, the reduce part chains all of them together to form a single function. What do we want to do with each function as they come out from the stream ? We want to combine them, this is done using the andThen, that is exactly done in the 2nd parameter to the reduce function.  The first parameter to the reduce method is an initial value, this is the identity function – given a function, just return the function. Every reduction needs a starting point. In this case, the starting point is the function itself.
  3. The chaining yields a Function<String,String> decorators.
  4. We just call the apply method to this using the parameter G’day Mate which passes it through the chain of functions( decorators) and finally sends that to the logger.log method.

This version of the decorator pattern is easier to understand, we simply took a message, added the timestamp to it , converted it to upper case and logged it.The Stream.of and the methods references being passed to it might seem difficult at the first read, but trust me it is more of a new way of solving the problem and an easier one in my opinion.

Conclusion

We took 2 examples of the decorator pattern but both examples have clarified that there is certainly an easier and better way to implement the decorator pattern. In both cases the decorator pattern using the functional style is definitely more concise and easier to understand. Code that is easier to understand is always easy to maintain. Can we safely conclude that we probably don’t need the typical decorator pattern anymore?

Well, in the examples that we considered, we had just one method or one functionality to decorate, the format method in the first example and log method in the second example. In these scenarios, the functional style definitely seems better and there is no need to go about creating different classes, the abstract class and then use the cryptic way of calling them. But what if we had more than a single method to decorate ? This is something that needs to be looked at and I will try and answer that in another post.

Command Pattern using Java 8 Lambdas

I have been looking at how to improve my knowledge of Design Patterns and at the same time sharpen my Java 8 skills too. I have begun to realize that one can combine the two and also realized that Java 8 Lambdas are extremely powerful.

In this post, we are going to take a look at how the implementation of the Command Design Pattern can be simplified using Java 8 Lambdas.

I have written another blog where you can understand the essence of the Command Design Pattern.

The example we are going to refactor using Java 8 Lambdas is from here. This article on the tutorialspoint site refers to the typical way of implementing the pattern. You must take a look at it to get a basic understanding of the domain/problem at hand. The following is not a UML but I have shown the main components for the example mentioned.

 

CommandPatternWithoutClient

In short , BuyStock and SellStock are 2 commands which implement the Order interface. Stock is the recipient and finally the Broker is the invoker. The Broker class deals only with the Order interface and has no idea about the concrete commands.

Let us implement the same using Java 8 Lambdas. The Order interface is a Functional interface and each ConcreteCommand above is really a function. Do we really a class to represent each Command ? Well, take a look at the client code now using Lambdas:

The Broker,Order interface remain the same and so does the Stock class. We can get rid of the individual Concrete Commands (BuyStock, SellStock) classes.

What we have done is actually passed behavior to the takeOrder method. This works as the Order interface has a method execute which takes no parameters and returns void. And hence () -> abcStock.buy() is a lambda expression which takes no parameters and returns void.

To understand this pattern better,  let us extend our problem. Imagine that in the same system, we had to sell Bonds too. The process of buying/selling stocks is different from bonds. With the Broker and the Order interface, the system can easily be extended with minimal changes.

NewCommandPattern

We added 2 more classes BuyBond and SellBond which implement the Order interface. These commands would invoke the Bond class( Receiver) which would perform the task of either buying or selling bonds. The Broker class remains untouched as it deals with only the Order Interface. Well, using Java 8 Lambdas, we don’t need the BuyBond or SellBond classes either.

The Command pattern can be implemented easily using Lambdas. One could argue that the Order interface has just 1 method and we haven’t considered the undo and redo commands in the Command Design pattern. We can always fall back on the typical implementation of the pattern in case we need an undo and redo in addition to the execute functionality.

Having said that, do we always need an Order interface which acts as the Command interface ? How about using the Runnable interface instead  to run all the commands?  It could affect the readability of the code a little bit but otherwise the use of Java 8 Lambdas really makes the implementation easy and powerful at the same time.

Function composition using Java 8

The objective of this blog post is to give you a basic idea of functional composition in Java 8. We will look at 2 methods, andThen and compose which are part of the functional interface, Function.  We will then build on it further to show how we can apply a stream to a variable number of functions to combine all the functions.

Let us take a very simple example of 2 functions, one function adds 0.2 to an incoming value and another one adds 0.5 to an input value. So the input is a double and the output is also a double. This can represented as a Function<Double,Double>. Function is the functional interface introduced in Java 8.

Function<Double, Double> func1  =  d -> d + 0.2;
Function<Double, Double> func2  = d -> d + 0.5;

Both andThen and compose are default methods.

The andThen method:

To compose these 2 functions together , we can use andThen method from the Function interface. What do we get now ?

func1.andThen(func2)

Let us start with an initial value, 1.0.

Hence :

func1.andThen(func2).apply(1.0)

This gives us an output of 1.7.

How ?

  1. The call to the andThen method first applies the func1 to 1.0 which is the input. This gives us an output of 1.2 as behavior of func1 is d -> d+0.2, here d = 1.0
  2. The output from above , 1.2 , serves as an input to func2 and hence we get 1.2+0.5 = 1.7.

The compose method:

To understand this let us slightly modify the 2 functions:

Function<Double, Double> func1 = d -> d + 0.2;
Function<Double, Double> func2 = d -> d * 10.0;

The second function multiplies the incoming value by 10.

If we were to do:

func1.compose(func2).apply(1.0)

The output is 10.2

How?

  1. The call to the compose method first applies the func2 to 1.0 which is the input. This gives us an output of 10.0 as behavior of func2 is d -> d * 10.0, here d = 1.0
  2. The output from above , 10.0 , serves as an input to func1 and hence we get 10.0 + 0.2 = 10.2

What if we applied andThen to the above?  Well, the output is 12.0 . Surprised ?

Why?

  1. The call to the andThen method first applies the func1 to 1.0 which is the input. This gives us an output of 1.2 as behavior of func1 is d -> d+0.2, here d = 1.0
  2. The output from above , 1.2 , serves as an input to func2 and hence we get 1.2 * 10.0 = 12.0.

Remember:

The andThen method applies the first function, func1 to the input, that is the parameter to the apply method but the compose method operates by applying func2 to the value in the apply and then passes the value to func1.

andThen:

func1.andThen(func2).apply(1.0)

compose:

func1.compose(func2).apply(1.0)

More fun with functional composition:

Let us go back to :

Function<Double, Double> func1 = d -> d + 0.2;
Function<Double, Double> func2 = d -> d + 0.5;

When we did the following, we got the output as 1.7 :

func1.andThen(func2).apply(1.0)

Let us apply a Stream.of to func1 and func2.

The output from this is also 1.7

The Stream.of(…) returns a stream of Function<Double,Double>. The reduce method takes a Function.identity(), this is just saying, hey whatever is the next element in the stream, return it to me as it is. The Function::andThen specifies that combine each element in the stream with  andThen(). So <element_from_the stream>.andThen<next_element_from_stream>. The combination of stream and reduce method combines or chains all the functions together and gives us a single Function<Double,Double> which is a chain of functions.

Now how is this useful ? We can create a function which accepts  a variable number of functions and then they can all be chained in one place.

Output from all 3 types:

1.7
1.7
1.7

We used a very simple Function<Double,Double> which just added a double value but we could easily pass and chain functions which do a lot more.Function composition is a powerful mechanism which can be used to solve a variety of problems.Think about the decorator pattern or how consecutive filters are applied , can’t we use functional composition instead ?

Strategy design pattern using Lambdas

I was recently reviewing some code and was thinking of solving a code smell that I came across. It seemed to me that the Strategy pattern would be a good fit to solve the code smell. Well, honestly , I am not a big fan of design patterns in every code smell but I feel they can surely be used in cases where it is appropriate. I consider design patterns as a common vocabulary to solve problems.

I don’t remember the exact implementation of most of the design patterns at the back of my head and so I started reading about the Strategy pattern on wiki :  Strategy pattern on wiki. If you are not aware of the pattern at all, I would recommend that you read  about the pattern first before looking at the Java code on wiki.

The problem the code sample tries to solve is using a billing strategy at runtime to generate  the Customers bill. Customer class can use a NormalStrategy or use a HappyHourStrategy. The code is open for extension in case we decide to use a third strategy to bill the customer.

At  the  end of the Java code sample, the wiki page mentions that there is a much simpler example in modern java using Lambdas. When I clicked that link, it showed an altogether different example. Well, I got a little curious and decided to solve the same Customer bill generation problem using Lambdas.

Thought process:

The strategy pattern has an interface and the example above uses 2 concrete implementations of the strategy. If I could replace it with a lambda, what do I need to focus on ? The 2 implementations of the strategy are quite simple, what do they do ? They take a double as a parameter and return a double. Can I represent this using a lambda ? Yes, I can. There is a functional interface in Java 8 called Function, it takes one type as input and returns/produces another type:

public interface Function<T, R>

And so we can do this :

private Function<Double, Double> billingStrategy;

Refer to the code on wiki, Customer constructor takes a BillingStrategy:

public Customer(BillingStrategy billingStrategy){
             this.billingStrategy = billingStrategy;
}

This can now be replaced :

public Customer(Function<Double, Double> billingStrategy){
             this.billingStrategy=billingStrategy;
}

The add method in the Customer class is:

public void add(double price, int quantity){
     drinks.add(billingStrategy.getActualPrice(price * quantity));
}

Instead of the implementation of the billing strategy, we now have a billingStrategy which is a Functional interface(Function)

public void add(double price, int quantity){
       drinks.add(billingStrategy.apply(price * quantity));

And so now the full code:

Customer.java

StrategyPatternWiki.java

What has changed:

  1. The billing strategy has been declared using a Function and lambda.
    • The class NormalStrategy takes a rawPrice and returns the rawPrice and hence we can do this:                                                                                                              Function<Double, Double> normalStrategy =  (Double d) -> d;
    • The HappyHourStrategy takes a rawPrice and gives a 50 % discount and hence we can do this :                                                                                            Function<Double, Double> happyHourStrategy =  (Double d) -> d * 0.5;
  2. This is being passed to the Customer constructor.
  3. The setStrategy method now takes a Function<Double,Double>

Notice that we have no reference to the BillingStrategy interface or the 2 classes which implement the BillingStrategy interface.

Using lambdas and the functional interface helped us replacing the Strategy pattern which defines an interface and different classes which implement the interface. We simply used functions, not normal functions but higher order functions. The alternative way of solving the same problem using lambdas and functional interfaces is quite powerful.

We could do better:

BillingStrategy.java

Notice that this is a class with static methods. It has behaviour for the 2 strategies

StrategyPatternTest.java

The code change is  the usage of the method references.

Function<Double, Double> normalStrategy = BillingStrategy::getNormalStrategy;
Function<Double, Double> happyHourStrategy = BillingStrategy::getHappyHourStrategy;

Well it looks like Java 8 lambdas, methods references and the functional style of programming have opened up new and really interesting ways of solving recurring problems in our code.The next time you encounter a Strategy pattern, think of lambdas and the Functional Interface, Function.

Java 8 Streams

The objective of this post is to introduce you to Streams in Java 8 by answering some very basic questions.

What is a stream?

Let us take a slightly abstract view first. Imagine a pipe, a pipe with 2 open ends. One end, the input end, is connected to a source, and the other end is connected to the destination. Let us assume that the source here contains data.The data from the source will then flow through the pipe and possibly undergo transformation. The desired data then flows out from the other end.

Data from the source does not start flowing through the pipe the moment the input end of the pipe is connected to the data source. It only starts flowing and reaches the destination when a knob is turned on.

A stream is nothing but a pipe. The pipe here is an abstraction and so is the stream. A stream enables the flow of data from the source to the destination and it could undergo transformation on its way. A stream does not hold any data.

How do we create a stream/pipe?

The stream API is part of the java.util.stream package. It can be obtained in many ways, some of the common ways include the following:

  • From a collection : The stream method is a default method that has been added to the Collection  interface.A stream can be attached to any class that implements the Collection interface.The collection of persons here acts as a source of the data.
List<Person> persons =  // initialize list of people

Stream<Person> persons = persons.stream()

  • From static factory methods like Stream.of() :
Stream<Integer> numbers = Stream.of(1,2,3,4,5);
  • Files.lines() which returns each line of a file as a stream:
Stream<String> lines = Files.lines(Paths.get("C:\\TestFile.txt"));

What do we do with a Stream?

We saw a few ways above to get a reference to a stream/pipe. But what do we do with a stream? To get an answer to that, let’s think about what do we do with collections in java? We iterate through collection and pick up the relevant data that we need. The relevant data is obtained by applying some conditions, this is nothing but filtering. So in short, as we iterate, we filter it and then collect the data. Pay attention to these 3 words in italics. Iterate, Filter, Collect. These are some of the common operations that we would usually perform on a stream.

  • Iterate through a collection/data source:

 This is actually done implicitly for us using the stream method we discussed above.  Remember that there needs to be a trigger for the data to flow through the pipe. We  will discuss this soon but we did refer to this as the knob that makes the data flow  through the pipe. Once the knob is turned on, the stream method will push the data  down the pipe. 

Streams_Basic
Calling the stream() does not result in data flow

Example:

List<Person> persons =   // list of people

persons.stream()

  • Filter:

Once we have a stream/pipe and data begins to flow through it, we usually filter the data that moves through the pipe. This is done by using some conditional logic as we move through the data pipe. In Java 8, we use the filter method on the stream API to do this. The filter method looks like this:

The signature of the filter method:

Stream<Tfilter(Predicate<? super T> predicate)

The return type is a stream. The parameter to the filter method is a Predicate which is a functional interface.The data element will be evaluated using this filter, if it passes the criteria, it moves ahead in the pipe else it gets dropped out.

Example:

persons.stream()

                .filter(person -> person.getCitizenship() == Citizenship.USA)

Filter_Basic

 

Here the person-> person.getCitizenship == Citizenship.USA is a lambda expression that is mapped to the Predicate above.

  • collect:

So we created a stream and wrote a filter. Assuming that the data now flows through the pipe and passes through the filter and reaches the end of the pipe, what do we do now? We collect the data that we want. This is done using the collect method. The collect () API does exactly what it means, it collects the data. We can specify the final data structure into which the data needs to be collected.

Remember the knob we spoke about earlier. Unless the knob is turned on, nothing passes through the pipe and hence nothing gets filtered. The collect method is one such example which acts as the knob, it is called the terminal operation. Unless we call a terminal operation nothing happens! This makes the streams extremely lazy.

lazy_garfield

To summarize, using steps 1, 2 and 3 above, we created a stream, pushed the data down the stream, filtered it and then collected it.

Example:

The Collectors is a utility class which helps in accumulating elements into a collection as shown below.

Filter_Collect

 

 

Other simple examples to understand stream, filter, collect:

Get a list of all men from a collection of Person objects

Get a list of all women who are Canadian citizens:

 

Why Streams?

This topic deserves more attention and will be covered in another article but a short answer to the same would be that they bring functional style of programming to Java. There are many more operations like map, flatMap, sort etc which can be chained together to transform and sort objects. Streams do not create any temporary data structures, it is all 1 pass.  So the filter operation does not create any temporary data structure.Streams also open up the gates for parallel processing by exploiting the underlying hardware. This can be done by calling the parallelStream() instead of the stream method above.

There are many other operations than be called on the stream and the same will be covered in other posts.

 

Java 8 Lambdas – A brief introduction

Let us say that you are in a hurry, you do not know the local language and you need directions to travel from point A to point B. You finally see just one stranger on the road who can speak in your language and this is how he instructs you to get to point B:

  1. Walk straight for about a 100 metres and around the corner take a right. Hey, on your way don’t  forget to notice my favorite restaurant which serves the best pasta.
  2. Once you take a right, walk straight down for another 100 metres, and take a left. During the 100 m walk, you will see a gymnasium, that is where I work out.
  3. Then your destination will be on the right side but before you cross over to the other side, don’t forget to look at the beautiful tower clock.

If you are really in a hurry and not hungry, do you really care about the pasta and the tower clock ? Well anonymous classes in Java are a bit like this. You setup a lot of instructions before the actual set of instructions that we are really interested in.

When you sit in a plane, do you go to the pilot and tell him how to get to the destination?  You don’t !  You sit in the plane and let the pilot do the job for you.  And well, pray that he does it well☺ !

Why am I talking about Anonymous classes ? You must be thinking  – Do I have to learn that now to understand lambdas? Aren’t they kind of ugly? Yes, you are right, they are! But sometimes, things in life can get ugly and if I may get a little philosophical, ugly things in life make you stronger and probably motivate you to do the same things in a better way.

Let us take a simple example:

Take a look at the code above and you will probably feel like this :

Confused_Lambdas

If you asked an experienced developer on your team (so called expert), they might say : That is nothing but an anonymous inner class which implements the Runnable interface. Once you implement the Runnable interface, you override the run method. The computation that we need to perform in another thread is written in that run method.

Lambdas_Funny

We had to do so much to print that line in the run method so that it executes in another thread. Is there a better way to do that? Let us give it a try, let us break that down a little bit.

What are the parameters to the run method? None. What is the run method doing? Just that one single line which prints a message. Our main focus is the run method which takes no parameters and performs some computation. So we could represent the parameters to the run method as () indicating empty parameters. The body of the method is System.out.println(“Do something in the thread”) and now let’s combine the two.

What do we get ?

() - System.out.println(“Do something in the thread”);

Let us a use a different separator, the ->. The -> is just a separator between the parameters to the run method and the body of the method.

() -> System.out.println(“Do something in the thread”);

And well, that is a lambda expression!

So we can actually replace the code using anonymous class as:

So we have been able to refactor our code from:

To:

That surely looks a lot better. This code is quite clear in conveying what we really intend to achieve in the thread, unlike the stranger who gave us a lot of instructions which was not really useful.

Are lambdas just a replacement for the inner class syntax above? Is the compiler doing the same thing behind the scenes?

No, it isn’t! When we write an anonymous class using the anonymous class syntax and compile our code, we actually get 2 classes. <ClassName>.class and <ClassName$1>.class. When we use the lambda expression, we get just 1 .class file. That is one of the most important differences between an anonymous inner class and a lambda expression. How this really works behind the scenes will be covered in another article. But to give you a heads up, this is done using  a byte code instruction called the invokedynamic that was introduced in Java 7.

How did we manage put a lambda in place of an anonymous class?

Instance of a Thread class takes a Runnable:

Thread t = new Thread( Runnable target);

Runnable is an interface. We started with an anonymous class which was then replaced with a lambda.

Thread t = new Thread( () -> System.out.println(“Do something in the thread…”));

So it means, we actually managed to do this:

Runnable target = () -> System.out.println(“Do something in the thread…”);

Well, the Runnable interface has been there in the JDK library right from the beginning.How did we just manage to replace all of that code with a lambda ? This is because Runnable is an interface, it has just one method, the run method. This is now called a functional interface – An interface with 1 abstract method. Runnable has just one – run().

@FunctionalInterface
public interface Runnable{
void run();
}

Thread class takes Runnable and we can assign a lambda to Runnable since it is a Functional interface. The signature of the run method gives us an insight on the lambda expression.The return type is automatically inferred by the compiler.

A lambda expression can take multiple parameters:

(int a, int b) -> a+b;

A lambda expression can also have multiple statements:

() ->{
System.out.println(“One”);
System.out.println(“Two”);
};

Lambdas that  have multiple statements need to be enclosed in curly braces. We must try and avoid having too many statements in the curly braces above as this will defeat one purpose of lambdas – clarity in code. If you see the body of the lambda getting too big, replace it with a function.

To solidify our understanding , let us go through another example.

Let us sort a list of strings by their decreasing length using a Comparator.

The 2nd parameter to the sort method is an instance of Comparator. What do we really want to do in the code above ? We want to sort strings by their length but landed up doing a lot more.

Is this a good candidate for Lambdas ?  Let us find out by asking the following questions

  1. Is there an instance of an anonymous inner class- Yes
  2. Does Comparator have only 1 abstract method – Yes

Let us go ahead and replace it with a lambda like we did it with Runnable.

  1. What parameters does the compare method take – 2 Strings.
  2. What is the method doing – comparing the length

(String s1, String s2) -> s1.length() < s2.length() ? 1 : -1

Let us replace the code:

In fact, the compiler is smart to know that we are sorting a list of Strings. Hence the same code can be written without mentioning the type of s1 and s2.

We assigned the behavior of comparing strings by length to type Comparator.

To summarize, lambdas:

  1. Help us concentrate on what we want to do rather that how to do it
  2. Pass behavior to function which can be a very powerful mechanism. 
  3. Are anonymous functions that map to functional interfaces.

Finally, I hope we have been able to move our state….

Confused_Lambdas Happy_Lambdas