Saturday, June 4, 2016

NIO.2 Asynchronous file I/O with Future and CompletionHandler

Recently I had a requirement to work with lot of I/O type of work and at the same time a lot of computation.So what Immediately a solution comes to mind that we will start a configurable number of threads.And the job of each thread will do the I/O independently and then after start the computation.But here one thing to observe that my computation has a very little to do with  the I/O.But in this design  my thread is not doing any  useful when it is doing the I/O and after the completion of the I/O the thread is going for computation.But it would be great if my thread can be free once it starts the I/O and without waiting to complete the I/O  jumps to the computation part.And some one  informs my thread once the I/O  completes.Till that my thread is busy with doing some useful calculation.

So here we get the two benefits.My thread is not waiting for I/O to complete and at the same time , it is doing some useful calculation.Here note that the job of my thread is both I/O bound and CPU bound.

Asynchronous  I/O :


NIO.2 provides support for  asynchronous  I/O(connecting, reading, and writing). In a synchronous  I/O, the thread that requests the I/O operation waits until the I/O operation  completes.In an asynchronous  I/O, the  application requests the system for an I/O operation and the operation is performed by the system asynchronously. When the system is performing the  I/O operation, the application continues doing some other useful computation  work. When the system finishes the  I/O, it notifies the application about the completion of I/O operation.


Four asynchronous channels are added in NIO.2 (java 7) to the java.nio.channels package:

  •     AsynchronousSocketChannel
  •     AsynchronousServerSocketChannel
  •     AsynchronousFileChannel
  •     AsynchronousDatagramChannel
       
Here  we take AsynchronousFileChannel  as our example and try to understand the asynchronous I/O.

The AsynchronousFileChannel provides us two different ways for monitoring and controlling the initiated asynchronous operations.

 The first one is by returning a java.util.concurrent.Future object, which poses a Future object and can be used to enquire its state and obtain the result.It follows a poll type approach.

The second is by passing to the  I/O operation an object of a new class, java.nio.channels.CompletionHandler, which defines handler methods that are executed after the operation is completed.It follows a push type approach.

Each method of the AsynchronousFileChannel class that supports asynchronous file I/O operation has two versions.One for Future object and another for CompletionHandler object.

Example of poll approach using Future object:



package com.brainatjava.test;
import static java.nio.file.StandardOpenOption.CREATE;
import static java.nio.file.StandardOpenOption.WRITE;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousFileChannel;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.concurrent.Future;

public class AshyncronousIOWithFuture {
static String str="write some meaning full text to file,which is desired for your applications.";
        public static void main(String[] args) {
        long startPosition=0;
        Path path = Paths.get("/home/brainatjava/mytest");
        try (AsynchronousFileChannel asyncFileChannel =
         AsynchronousFileChannel.open(path, WRITE, CREATE)) {
        ByteBuffer dataBuffer = ByteBuffer.wrap(str.getBytes());
        Future result = asyncFileChannel.write(dataBuffer, startPosition);
        while (!result.isDone()) {
        try {
        //remember in real life scenario the initiating thread will not sleep but it will  do some useful work.
        System.out.println("Sleeping for one seconds before the next pooling.We will continue to keep pooling in each one second.");
        Thread.sleep(1000);
        }
        catch (InterruptedException e) {
        e.printStackTrace();
        }
        }
       
        System.out.println("Now I/O operation is complete and we are going to get the result.");
        try {
        int resultbytewritten = result.get();
        System.out.format("%s bytes written to %s%n",
        resultbytewritten, path.toAbsolutePath());
        }
        catch (Exception e) {
        e.printStackTrace();
        }
        }
        catch (IOException e) {
        e.printStackTrace();
        }
        }
        }

In the example above first we create an AsynchronousFileChannel for writting. Then we use the write method to write some data,which return a Future object. Once we get a Future object, we  use a polling method method to handle the result of the asynchronous file I/O, where it keeps calling the isDone() method of the Future object to check if the I/O operation is finished or not.And rest of the code is self explanatory.But note that while checking the result of future object we are taking a 1 second sleep,    but in real life we  we will do some useful calculation there.

Example of push approach using CompletionHandler object:


 This version of the write method of the AsynchronousFileChannel class  allows us pass a CompletionHandler object whose methods are called when the requested asynchronous I/O operation completes or fails.

CompletionHandler interface is defined in the java.nio.channels package.

The type parameters:

    V – The result type of the I/O operation
    A – The type of the object attached to the I/O operation

The CompletionHandler interface has two methods: completed() and failed(). The completed() method is called when the requested I/O operation completes successfully. the failed() method is called ,when the requested I/O operation fails. The API allows  us to  pass an object of any type to the completed() and failed() methods. Such an object is called an attachment.We may want to pass an attachment such as the ByteBuffer or the reference to the channel or an reference to the I/O source etc. to these methods such that we can perform additional actions  inside these methods.For example we want to close the AsynchronousFileChannel once the async I/O operation completes successfully or fails due to any reason.We can also pass  null as an attachment , if we don't want to do anything usefull.
Lets create an Attachment object first

public class Attachment {

private Path filesource;
private AsynchronousFileChannel asyncChannel;


//getters and setters goes here.

}

Now let's define the CompletionHandler

private static class MyWriteCompletionHandler
implements CompletionHandler {
@Override
public void completed(Integer result, Attachment attachment) {
System.out.format("%s bytes written to %s%n",
result, attachment.path.toAbsolutePath());
try {
attachment.asyncChannel.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void failed(Throwable e, Attachment attachment) {
System.out.format("I/O operation on %s file failed." +
"with  error is: %s", attachment.path, e.getMessage());
try {
attachment.asyncChannel.close();
}
catch (IOException e1) {
e1.printStackTrace();
}
}
}


public class ASyncIOWithCompletionHandler{

 public static void main(String[] args) {
static String str="write some meaning full text to file,which is desired for your applications.";
 Path path = Paths.get("/home/brainatjava/mytest");
 try {
AsynchronousFileChannel asyncfileChannel =
AsynchronousFileChannel.open(path, WRITE,CREATE);
MyWriteCompletionHandler handler = new MyWriteCompletionHandler();
ByteBuffer dataBuffer = ByteBuffer.wrap(str.getBytes());
Attachment attachment = new Attachment();
attachment.setAsyncChannel(asyncfileChannel);
attachment.setPath(path);
asyncfileChannel.write(dataBuffer, 0, attachment, handler);

try {
System.out.println("Sleeping for 10 seconds...");
Thread.sleep(10000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Completed");
}
catch (IOException e) {
e.printStackTrace();
}
 }
}

Here the main thread is  sleeping for 10 seconds ,but in real life scenario , the main thread will do some useful calculation rather than sleeping.

Sunday, May 8, 2016

Remote debugging Tomcat with Eclipse

Sometimes it is required to debug a remote  application that is deployed in tomcat in the local network.We can configure eclipse to  debug the remote application locally  for a running tomcat instance that is configured with JPDA support.JPDA is a multi-tiered debugging architecture.Please visit the oracle docs for more about JPDA.

First let's set up tomcat for remote debugging using JPDA

Setting Up Tomcat For Remote Debugging

 Tomcat can be configured to allow a program such as eclipse to connect remotely using JPDA and see debugging information.We can do the configuration change in catalina.sh.Now open the catalina.sh or catalina.bat and find the line JPDA_TRANSPORT.Chnage the value of the parameter as  

JPDA_TRANSPORT=dt_socket
JPDA_ADDRESS="ipwhereyourapplicationisdeployed:5001" (port 5001 is not mandatory, you can give any unused port)

Here also we can write  JPDA_ADDRESS="*:5001" ,but it has some security issue,so it is good practice to specify the ip.

Then we start tomcat with the command ./catalina.sh jpda run.And now we are ready to go.

Also without changing anything in catalina.sh or catalina.bat , we can write the same parameter in startup.sh or startup.bat  

In Unix
export JPDA_ADDRESS=ip:5001
export JPDA_TRANSPORT=dt_socket
bin/catalina.sh jpda run
In Windows
set JPDA_ADDRESS=ip:5001
set JPDA_TRANSPORT=dt_socket
bin/catalina.bat jpda start
 Once we  have tomcat configured , now we start tomcat manually from command line.


Now we configure our eclipse to listen the tomcat running remotely.

Setting Up Eclipse:

1.Set break point in eclipse.
2.Then Debug As Debug Configurations...
3.Then double click on the heading Remote Java Application.A window like this will appear

4.In the host write the ip address you mentioned in the JPDA_ADRESS and in port write the port you mentioned in JPDA_ADDRESS.Here in our case it is 5001.
5.Now click apply and debug.

Now the  eclipse is ready for debugging.

The above scenario is tested in  Linux Mint 17.1 Rebecca ,STS 3.7.2 and apache-tomcat-8.0.24.

Saturday, April 23, 2016

Redis Pub Sub with Jedis

Within these days we were working on a project which heavily relies on Redis for its data sync process.To give  more clarity here we are briefing  the scenario.

There are two parts on the system.One is a producer which is making some cache in Redis and another is a consumer which is subscribed to the same Redis.The subscription is through a channel.The consumer is subscribed to the channel.When there is some change in the channel ,it is published to the consumer and the consumer  updates itself accordingly.Here we used Jedis as Redis  client.



In Redis, we can subscribe to multiple channels and when someone publishes messages on those channels, Redis notifies us  with published messages. Jedis provides this functionality with JedisPubSub abstract class. To handle pub / sub events, we need to extend JedisPubSub class and implement the abstract methods.



package com.brainatjava.test;
public class xyzListener extends JedisPubSub {   @Override
    public void onMessage(String channel, String message) {
    System.out.println(message);
}

Now we wrote the code for registering listener in a different class.

public class TestProgram {
private void registerListeners() {
        if(!xyzListener.isSubscribed()){
                Runnable task=()->{       
                try{
                    Jedis jdeisConnection=    ((Jedis) redisTemplate.getConnectionFactory().getConnection().getNativeConnection());
                    jedisConnectionExceptionFlag=false;
                    jdeisConnection.subscribe(lineItemDeliveryListener, "channelName");
                      
                }
                catch(JedisConnectionException jce){
                    logger.error("got jedis connection excpetion "+jce.getMessage(),jce);
                    jedisConnectionExceptionFlag=true;
                }
                catch(RedisConnectionFailureException rce){
                    logger.error("got jedis RedisConnectionFailureException excpetion "+rce.getMessage(),rce);
                    jedisConnectionExceptionFlag=true;
                }
                catch(Exception e){
                logger.error("error in registerListeners "+xyzListener.isSubscribed(),e);
            }};
           
            Thread xyzUpdater = new Thread(task);
            xyzUpdater.setName("xyzUpdater");
            xyzUpdater.start();
        }
    }

}
Here if we notice the above code ,we found that  first we are checking is xyzListener is subscribed to the required channel ,if not we are doing it.But Observe that we are doing it in a hacky way.That is we are getting the native connection first and then we are subscribing to the channel.And the subscribe is a blocking call.It act in wait and watch mode.

So when there is a change in the channel the listener listens it and update its cache accordingly.But There is always should have a fail safe mechanism in place.We have also done that.If somehow Jedis pubsub is not working,then we have a mechanisim in place to do it manually.

The mechanism is like we have a cron scheduler running in every 15 minutes and    checking the cache timestamp and if the cache timestamp of the latest cache and the timestamp of the consumer varies, then we assume there is issue with pubsub and we will update the consumer cache manually.

With this design everything was fine and  the 15 minutes cron was their without any use.After the smooth working of some days we got an alert that the 15 minute cron is running and manually updating the cache.So it has no impact on our service as the cache is getting updated manually with the help of cron scheduler.

But why this happened?After investigetting sometimes we found before some  days the redis was restarted.And this created the whole issue.It is behaving like it is subscribed.Now you know the solution.

Friday, March 11, 2016

The try-with-resources Statement

It is always required to close the resources like database connections, file handles like BufferedReader,BufferedWriter etc after it's use.Otherwise we will face resource leak issue.And sometimes we forget to close the resources after the use.But in Java 7 a functional interface namely AutoCloseable is introduced.And resoureces like Connection ,BufferedReader and BufferedWriter etc extends AutoCloseable.
The try-with-resources statement is a try statement that declares one or more resources. The try-with-resources statement ensures that each resource is closed at the end of the try statement. Any object that implements java.lang.AutoCloseable,  can be used as a resource inside the try-with-resources statement.
The following example writes a line in a file. It uses an instance of BufferedWriter to write data in the file. BufferedWriter is a resource that must be closed after the program is finished with it:
static String writeALineToFile(String path) throws IOException {
    try (BufferedWriter bw =
                   new BufferedWriter(new FileWriter(new File("path")))) {
        return bw.write();
    }
}
In this example, the resource declared in the try-with-resources statement is a BufferedWriter. The declaration statement appears within parentheses immediately after the try keyword. The class BufferedWriter, in Java SE 7 and later, implements the interface java.lang.AutoCloseable. Because the BufferedWriter instance is declared in a try-with-resource statement, it will be closed regardless of whether the try statement completes normally or abruptly (as a result of the method BufferedWriter.write throwing an IOException).

Let's make it clear that here try-with-resource statement and try block are two different things.

Prior to Java SE 7, we can use a finally block to ensure that a resource is closed regardless of whether the try statement completes normally or abruptly. The following example uses a finally block instead of a try-with-resources statement:

static String writeALineToFileWithFinally(String path)
                                                     throws IOException {
 try {
       BufferedWriter bw =
                   new BufferedWriter(new FileWriter(new File("path")))) ;
         bw.write();
    }
}
    } finally {
        if (bw != null) bw.close();
    }
}
However, in this example, if the methods write and close both throw exceptions, then the method  
writeALineToFileWithFinally   throws the exception thrown from the finally block; the exception thrown from the try block is suppressed.

But In contrast, in the example readFirstLineFromFile, if exceptions are thrown from both the try block and the try-with-resources statement, then the method readFirstLineFromFile throws the exception thrown from the try block; the exception thrown from the try-with-resources block is suppressed.

We  can retrieve the suppressed exceptions by calling the Throwable.getSuppressed method from the exception thrown by the try block.


Note: A try-with-resources statement can have catch and finally blocks just like an ordinary try statement. In a try-with-resources statement, any catch or finally block is run after the resources declared have been closed.

Saturday, March 5, 2016

Java 8 Lambda Expressions-Continued

As we see in the previous series Lambda expression,we used an Functional interface and created a Lambda expression by removing the anonymous inner class code.

Here we will see that we can do the same job without using our custom functional interface.But here we will take the help of some of the inbuilt functional  interfaces which is provided in java8 in package java.util.function.



@FunctionalInterface
public interface Predicate <T>{
  boolean test(T t);
.
.
.
.
}

Here parameter T is the type of the input to the predicate
Here the Functional Interface Predicate given in package  java.util.function represents a boolean-valued function(predicate) of a single argument.It has one abstract method test(Object obj).

Let's see the example below


package com.brainatjava;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
public class Test {
    static List wordList = Arrays.asList(new String[]{"a","b","Lambda","d"});
    public static void findString(List list, Predicate predicate) {
            for (String p : list) {
                if (predicate.test(p)) {
                   System.out.println("we found Lambda anonymously.");
                }
            }
        }
    public static void main(String[] args) {
        findString(wordList,x->x.equalsIgnoreCase("Lambda"));
    }
}


Now let's see some other built in functional interfaces and it's use case.

@FunctionalInterface
public interface Function {
     * Applies this function to the given argument.
     *
     * @param t the function argument
     * @return the function result
     */
    R apply(T t); ....
....
//along with some other methods

}

It has an abstract method namely apply having argument T and return type R.
Suppose we have a requirement to take some strings and convert those into doubles.
So we will take the help of the apply() method of the above  functional interface.
So we wrote a method namely changeFormat like below.

public static List changeFormat(Function function, List source) {
        List sink = new ArrayList<>();
        for (T item : source) {
        R value = function.apply(item);
        sink.add(value);
        }
        return sink;
        }


package com.brainatjava;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;

public class Test {     public static void main(String[] args) {
        List digits = Arrays.asList("1","2","9","7","5");         List numbers = changeFormat(n->new Double(n), digits);
    }

I request you to visit the official documentation from oracle to get  the knowledge of all available functional interfaces in java.util.fuction package those provide target types for lambda expressions and method references.

Friday, March 4, 2016

Method Refernce(double colon operator) vs Lambda Expression in Java 8

In our previous post we saw that we can use lambda expression to implement function interface.But it is not the only way to implement functional interface. A new feature introduced in Java 8 known as Method Reference.It has the ability to replace an instance  of functional interface with a method having same argument as the method of the functional interface.Usually in Java :: operator is used for method reference.The method in the functional interface and the passing method reference should match for the argument and return type.
Let's take an example

package com.brainatjava;

import java.util.Arrays;

import java.util.List;

import java.util.function.Predicate;

public class Test {

    static List wordList = Arrays.asList(new String[]{"a","b","Lambda","d"});
    public static void findString(List list, Predicate predicate) {
            for (String p : list) {
                if (predicate.test(p)) {
                   System.out.println("we found Lambda by method expression.");
                }             }         }     public static void main(String[] args) {         Predicate predicate=Test::check;         findString(wordList,predicate);     }     public static boolean check(String value){         return value.equalsIgnoreCase("Lambda");     } }

@FunctionalInterface
public interface Predicate {
    boolean test(T t); }
Here if we  look at the findString() method, we see that a functional interface named Predicate is used.And we used the abstract method test() of the interface Predicate  to verify the result.

In our above example  we have defined method named check() in our class Test having same signature as method test() of funcational interface Predicate.So we can use method expression here.So in main method we call findString as findString(wordList,Test::check).By using method expression we utilized the existing method check().As we stated above that we can replace an instance of the functional interface with a method expression.So we could write  the line  Predicate predicate=Test::check.Here check is a static method of our class Test so we use it directly along with the class name.And used the instance of Predicate in findString method as findString(wordList,predicate).Just note the use of ::(double colon) operator , we are not calling the check() method,but we are only getting a reference to it's name.

Method reference are three types
1.Static Method References
2.Instance Method Reference
3.Constructor Method References

Now let's consider another functional interface namely Function provided in Java 8.

@FunctionalInterface
public interface Function <T,R>{

    /**
     * Applies this function to the given argument.
     *
     * @param t the function argument
     * @return the function result
     */
    R apply(T t);

....
....
//along with some other methods

}


It has an abstract method namely apply having argument T and return type R.
Suppose we have a requirement to take some strings and convert those into doubles.
So we will take the help of the apply() method of the above  functional interface.
So we wrote a method namely changeFormat like below.

public static  List changeFormat(Function function, List source) {
        List sink = new ArrayList<>();
        for (T item : source) {
        R value = function.apply(item);
        sink.add(value);
        }
        return sink;
        }

As we know that the job of a method refernece is to replace an instance of the functional interface.Now here we will do the same.But we know very well that Java has a constructor of Double class like below.

public Double(String s) throws NumberFormatException {
        value = parseDouble(s);
    }
If we observe here we find that the signature of the above Double constructor is similar with the apply method of the functional interface.
So we can replace the instance of the functional interface with the method reference.But this time we call it as Constructor Method References, as we are using a constructor here.So we can write the same as

Function function=Double::new;
By adding the above code segments in a main method ,our complete code look like below.
package com.brainatjava;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;

public class Test {
  
    public static void main(String[] args) {
        List digits = Arrays.asList("1","2","9","7","5");
        Function function=Double::new;
        List numbers = changeFormat(function, digits);
    }
public static List changeFormat(Function function, List source) {
        List sink = new ArrayList<>();
        for (T item : source) {
        R value = function.apply(item);
        sink.add(value);
        }
        return sink;
        }
  
}

Please refer the series java streams which always used with lambda expression for parallel processing.

Wednesday, February 24, 2016

Java 8 Lambda Expressions

In this blog we are going to discuss what is Lambda expression.And why it is needed.How to use it in Java.What are the benefits of using Lambda Expression.Has it some disadvantages of using it?Also we will learn about functional interface and default methods.We will move step by step from basics of Lambda Expression to its usage by simple code samples But before this we need to learn some of the backgrounds of Lambdas.

So we will learn about the followings first.
1.Functional interface
2.Anonymous inner class
3.Internal VS External iteration

1. Functional interface:

A Interface with only one abstract method are referred as Functional     Interface.But A functional interface can have more than one static or default methods .

The  below given example is a functional interface


public interface TestFunctional {

       void  doSomething(int x);

        static void staticMethod() {

              System.out.println("static method  in Functional Interface.");

           }

Some well known functional interfaces in Java are
1.java.lang.Runnable having only one abstract method  public abstract void run().
2 . java.util.concurrent.Callable<V> having only one abstract method  V call() throws Exception.
3.java.util.Comparator<T>  having only one abstract method   int compare(T o1, T o2) along with other default and static methods.

Note:We can write @FunctionalInterface to annotate the functional interfaces.
@FunctionalInterface
@FunctionalInterface

2.Anonymous inner class:

Let's take an example.Suppose we have a list of strings.And the requirement in hand is to check whether the list contains a specific string say "Lambda".
So what will we do here?There are many approaches to solve this problem.
Here we will consider the Anonymous inner class solution.

First let's declare an interface like 

package com.brainatjava;

public interface CheckWords {

    boolean test(String p);

}

package com.brainatjava;

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

public class Test {
    static List wordList = Arrays.asList(new String[]{"a","b","Lambda","d"}); 
    public static void findString(List list, CheckWords checkWord) {
            for (String p : list) {
                if (checkWord.test(p)) {
                   System.out.println("we found Lambda anonymously.");
                }
            }
        }
    public static void main(String[] args) {
        findString(wordList,new CheckWords(){
            public boolean test(String x){
                return x.equalsIgnoreCase("Lambda");
            }
});
}
}

Here notice that, we have no class which is implementing the CheckWords interface and overrides the test method.One of the arguments of the findString method is an anonymous class, which filters the strings with some conditions ie. which is equals to Lambda.This approach reduces the amount of code required because we don't have to create a new class for each condition that we want to test.Like if we want to find the string "closure" in the given list, we can write the anonymous class in the argument of findString method to check it.However, the syntax of anonymous classes is bulky

3.Internal VS External iteration:

External iteration is  the way by which we access the elements of the collection sequentially either by using a for each loop or by using an iterator.It restricts  the opportunity to manage the elements  of the collection by not  using reordering of the data, parallelism  etc.

Example:

1:By using for each

List charcters = Arrays.asList(new String[]{"a","b","c","d"});
 for(String charcter: charcters){
            System.out.println(charcter);
        }
 2:By using iterator

 List charcters = Arrays.asList(new String[]{"a","b","c","d"}); 
 Iterator iterator = charcters.listIterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
Sometimes it is required to consume the data of a collection in parallel or in random order which is suitable for the purpose of speed and efficiency.In this case we can avoid the sequential/insertion order  traversal of a collection .So  where order of the elements of a collection is not important  internal iteration help us to do the task in a parallel or random order.So we only have to tell what we want to do, but we don't need to specify in which order the elements will be processed.We leave this to the API to manage the order of the elements.

Introduction to Lambda Expressions:

Lambda expressions are anonymous methods that can replace the bulky code of anonymous inner class  that we described above.Simply we can say, it is a method without declaration.That is it has no name,no access modifier,no return type.And the method arguments have no type.As it will be clear from the context.We can say it is like a method we write in the same place where it will be in use.
We can say  Lambda expressions are implementation of only abstract method of a functional interface that is implemented by anonymous inner class.
It is useful where the method is used only once and the method definition is very short.It saves our effort of declaring a method with return type, name,access specifier and argument data types etc.
Lambda expressions are implementation
Lambda expressions are implementation
Lambda expressions are implementation of only abstract method of functional interface that is being implemented or instantiated anonymously. - See more at: http://java8.in/java-8-lambda-expression/#sthash.4TIhTUTQ.dpuf
Lambda expressions are implementation of only abstract method of functional interface that is being implemented or instantiated anonymously. - See more at: http://java8.in/java-8-lambda-expression/#sthash.4TIhTUTQ.dpuf

Lambda Expression structure: 

A Lambda expression has three parts
1.An arrow (->) token
2.argument list
3.body

(argument) -> (body) , is the structure of a valid Lambda expression.


argument list can have zero or more arguments.We can just think it like method arguments.

body of a Lambda expression can have zero or more statements.it can be a single statement  or a block of statements.No need to write return statements at the end of the body.The complete expression will be evaluated and returned.if the expression or statement evaluates to void ,then nothing will be returned.If the body contains a single statement no need to enclose it with curly braces.

Some Examples of Lambda Expressions:

 1.()->System.out.println("write something"); having zero argument and single statement in the body.
2.()->80 is also valid Lambda expression
3.(int x,int y)->{return x+y;} having two arguments and one statement

4.In section 2 Anonymous inner class section , We use Anonymous inner classes to instantiate objects of functional interface.Just  look at the line where we called findString() method in section 2, we used anonymous inner class to instantiate the functional  interface CheckWords.

The same can be done by Lambda expression.

public class Test {
    static List wordList = Arrays.asList(new String[]{"a","b","Lambda","d"});
    public static void findString(List list, CheckWords checkWord) {
            for (String p : list) {
                if (checkWord.test(p)) {
                   System.out.println("we found Lambda anonymously.");
                }
            }
        }
    public static void main(String[] args) {
        findString(wordList,x->
                 x.equalsIgnoreCase("Lambda")
            );
    }
}
Here we replaced the anonymous  innercalss with Lambda Expression.
What we have done here is   
CheckWords checkWord=x->x.equalsIgnoreCase("Lambda")           

That is we can write the above code as

 public  static void main(String[] args) {
 CheckWords checkWords=x->x.equalsIgnoreCase("Lambda")       
 findString(wordList,checkWord);
    }
5.As we discussed above that java.lang.Runnable is a functional interface,we can also use Lambda expression at the time of thread creation.

Let's first see the traditional  way of creating a thread.       

new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("implementing run method in an anonymous function.");
    }
}).start();
Now let's see the Lambda way of doing it.

new Thread(
    () -> System.out.println("implementing run method by Lambda expression")
).start();
The same can be written as 

Runnable runnable=  () -> System.out.println("implementing run method by Lambda   expression");   
  new Thread(runnable).start();
Lambda Expression Part2--->