Friday, October 10, 2014

Java Threads : simple introduction

Recently I was asked about the usage of threads in Java :
1- how to create them.
2- the difference between run() and start() methods.

first : how to create them.
I will talk about simply creating one thread at a time then starting it- there are ways to create thread pools then using or creating threads to be run at a later time which I will not mention.
you can create threads by:

a- creating a subclass of the Thread class:
    a1-  creating a subclass of the Thread class
    a2-  overriding the run() method to execute your code that you want to be run inside a different thread. 
    a3- create a new instance of your thread subclass
    a4- call the start() method of the new instance

b- creating a new class that implements Runnable interface
    b1-creating a new class that implements Runnable interface
    b2- provide an implementation for the run() method that will execute your code
    b3- create a new Thread instance and pass it an instance of your subclass that implements the        Runnable interface
    b4- call the start() method of the thread instance.


both will run your code inside a separate thread. But if you extend the Thread class then you fixed Thread as the parent of the class and since in Java you have only one parent class then it will restrict your code.
but if you implement the Runnable interface then you won't face this issue.



another question I was asked was the difference between calling the run() and the start() methods on the thread instances?
- calling run(): 
   1- will call the method and it will execute in the current thread
   2- you can call it multiple times on the same thread without problems.
  ==> the same as calling a method on any class

- calling start():
 1- will start the thread life cycle, it will go from New to RUNNABLE and eventually to 
      TERMINATED, and the run() method will be called which will execute your code
 2- your code will be executed in a different thread.
 3- if you call more than one time you will get an exception every time after the first one

Thursday, October 9, 2014

Lambda Expressions

Just recently  I was reading about JAVA 8 features and I came across Lambda expressions.
it seems that you can use what is known as Lambda expressions to write java code neatly.

from Oracle site:
"One issue with anonymous classes is that if the implementation of your anonymous class is very simple, such as an interface that contains only one method, then the syntax of anonymous classes may seem unwieldy and unclear"

Such Interfaces that have only one method without body are called functional interfaces. these interfaces are the ones that Lambda expressions help you implement are anonymous classes with simpler code.


Example:
package com.ahmadalzamer.lambda;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 *
 * @author Ahmad Al-Zamer
 */
public class TestLambdaExpressions {

    public static void main(String[] args) {
        //you can 
        List<String> l = new ArrayList<>();
        l.add("a");
        l.add("b");
        l.add("c");
        l.add("a1");
        l.add("b1");
        l.add("c1");
        l.add("a2");
        l.add("c2");
        l.add("b2");
        l.add("a12");

        System.out.println("Using Anonymous Classes:");
        System.out.println("original List:" + l);
        Collections.sort(l, new Comparator<String>() {

            @Override
            public int compare(String o1, String o2) {
                return o1.compareTo(o2);
            }
        });
        System.out.println("original List:" + l);

        //Using Lambda expressions:
        System.out.println("\nUsing Lambda Expressions:");
        l.clear();
        l.add("a");
        l.add("b");
        l.add("c");
        l.add("a1");
        l.add("b1");
        l.add("c1");
        l.add("a2");
        l.add("c2");
        l.add("b2");
        l.add("a12");
        System.out.println("original List:" + l);
        Collections.sort(l, (String o1, String o2) -> o1.compareTo(o2));
        System.out.println("original List:" + l);

        //Using Lambda expressions:
        System.out.println("\nUsing Lambda Expressions without Explicit data type:");
        l.clear();
        l.add("a");
        l.add("b");
        l.add("c");
        l.add("a1");
        l.add("b1");
        l.add("c1");
        l.add("a2");
        l.add("c2");
        l.add("b2");
        l.add("a12");
        System.out.println("original List:" + l);
        Collections.sort(l, (o1, o2) -> o1.compareTo(o2));
        System.out.println("original List:" + l);

        //Using Lambda expressions:
        System.out.println("\nUsing Lambda Expressions with multi-line body:");
        l.clear();
        l.add("a");
        l.add("b");
        l.add("c");
        l.add("a1");
        l.add("b1");
        l.add("c1");
        l.add("a2");
        l.add("c2");
        l.add("b2");
        l.add("a12");
        System.out.println("original List:" + l);
        Collections.sort(l, (o1, o2) -> {
            System.out.println("Comparing o1:"+o1+" to o2:"+o2);
            return o1.compareTo(o2);
        });
        System.out.println("original List:" + l);

    }
}


here you can see how I used Lambda Expressions to create an anonymous class that implements the Comparator interface.After that I used several Lambda expressions to implement the same Comparator.

Expression:(String o1, String o2) -> o1.compareTo(o2)  can be split as:
1) (String o1, String o2) : parameter list of the method defined in the functional interface, here you can either explicitly list the datatype of the parameters or the compiler can be implicitly infer them from the context.
2) -> : arrow token between parameter list and lambda expression body.
3) o1.compareTo(o1) : the body of the lambda expression, which will go inside the method of the functional interface. can be either a one line code - in which case you don't have to worry about the return keyword, the compiler will figure out whether to add it or not based on the interface- or you can use multi-line code block - in this case you are actually writing the body of the method of the function, so you have to add the return keyword if needed-



the ability to write neat code using Lambda expressions is nice to have but for people who are not used to them it will make the code look harder to understand.