I have been in the software development industry since 2010, working on enterprise product development using ADF. I am usually keen on learning about software design and emerging technologies. You can find me hanging around in the JavaRanch Forums where I am one of the moderators. Apart from Java, I am fascinated by the ease of use and simplicity of Ruby and Rails. Mohamed is a DZone MVB and is not an employee of DZone and has posted 58 posts at DZone. You can read more from them at their website. View Full User Profile

A Simple Application of Lambda Expressions in Java 8

05.04.2013
| 6292 views |
  • submit to reddit

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.





 

Published at DZone with permission of Mohamed Sanaulla, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Pyros Vallum replied on Sun, 2013/05/12 - 6:55am

Thanks for the example, but I think Java needs to focus on performance and refinement from hereon as when you say that you were 'trying to fit' lambda expressions into your code, it suggests to me that you were trying to justify its use and looking for a way to use it.  Code is complicated enough, if you make it too complicated, you will reduce its capacity for maintenance.  Remember KISS.  Java Engineers are trying to 'corner the market' on expression features and functionality.  Let's not 'saturate the market' with new expressions and instead, increase the quality of the 'product'.

Mohamed Sanaulla replied on Sun, 2013/05/12 - 1:36pm in response to: Pyros Vallum

the support for lambda expressions should have been there in the language quite sometime back- may be in the anonymous inner class time frame. But functional programming had not gone mainstream. But off late there has been a lot of focus on functional programming and lot of the concepts in functional programming help in writing good concurrent code. 

Its always important to identify where to fit in the feature and how to use it. The Java 8 release was delayed due to the importance given to the security fixes. Apart from lambda expressions there are quite a lot features in Java 8 which I am not aware of. And I am sure there would be performance related features aiming the quality of the product. 

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.