LAMBDA EXPRESSIONS IN ANDROID ( PART III )


I talked about basics of lambda expressions and method references, which are among the new features introduced in Java 8, in part I and part II of this series. Remember, not all the new features of Java 8 are available in Android. In this final part, I am going to explain about what changes you all have to make in build.gradle file , for using the two features in Android. The two features are supported in every version of Android, given that you make following changes on your build.gradle file

apply plugin: 'com.android.application'
//Android 1.0.0+ Gradle plugin
//as it contains DSL for jackOptions
android {
  compileSdkVersion 24
  //build tool version  21.1.1 and above
  // as it contains jack compiler
  buildToolsVersion "24.0.1"
  defaultConfig {
    applicationId "com.wordpress.laaptu.lambdawithandroid"
    //other stuff
    //jack compiler is needed if we are going to work with Java 8 features
    jackOptions.enabled true
  }
 //we need to specify that we are interested
 //in using Java8 features in compileOptions
  compileOptions {
    targetCompatibility 1.8
    sourceCompatibility 1.8
  }
}

This is all required , for you to work with lambda expression and method reference features in Android. You can check up this github link for the samples that use the two features of Java 8.  This is all for lambda expression in Android and do check upon following references for more

References

Lambda Expressions In Android ( Part II )


In Part I, I wrote the basics of lambda expression. I am going to write a little about what other methods that can be added to the interface definition (functional interfaces ) and method reference feature of Java 8.

Lambda expression is for interface with only one defined method. If there is other methods to be added on that interface, it will be default and static method definition and implementation only. Look at this link to know more. To illustrate this with example, let us take an interface

public interface IPrintStore {
    void  printName(String s);
}

Now we can easily write a lambda expression for this as

IPrintStore iprintStore = (s) ->
     System.out.println(String.format("You need to print this name =%s", s));
iprintStore.printName("Lambda");

We can only add and implement methods with modifiers default and static as in following example

public interface IPrintStore {
    void printName(String s);
    default void storeName(String s) {
        System.out.println(String.format("Store this %s to database", s));
    }
    public static String addExtraName(String s) {
        String value = s.concat(" :This is extra");
        return value;
    }
}

And use in the following manner

IPrintStore iprintStore = (s) ->
    System.out.println(String.format("You need to print this name =%s", s));
iprintStore.printName("Lambda");
iprintStore.storeName("Lambda");

This is all for functional interfaces in Java 8 and now let us focus on method reference feature of Java 8. As mentioned in Part I, lambda expression is only concerned with method signature ( arguments ) and method implementation ( code block )  of interface having a single method implementation. Method reference also works in similar manner and just like lambda , it is also concerned with arguments, code block and return type of a function.

 

screen-shot-2016-09-09-at-2-00-12-pm

Let’s take a simple analogy ( please don’t jumble up this example with classes and objects ). In order to be a mail man, a person needs to have a hair and a pair of shoes. So, all the person who has a hair and a pair of shoes can be treated as a mailman and those person would readily do the job of mailman.

Screen Shot 2016-09-09 at 4.33.30 PM.png

Now let us move this analogy, to our interface and it’s implementation. Let us create a simple interface named ICombine as

interface ICombine {
    void combine(int age, String name);
}

 

Let us analyze the method definition and signature or to say let us define the criteria which determines whether a function can be treated as object of ICombine

screen-shot-2016-09-15-at-11-12-53-am

 

So, just like mailman analogy, any instance method or static method having same return type or arguments as that of ICombine interface method, it can be treated as objects of ICombine.  So our criteria is a function should have void return type and should take two arguments where first argument must be of type int and second argument must be of type String. So, any method matching this criteria can be taken as ICombine’s object. Take a look at following illustration for it

Screen Shot 2016-09-15 at 11.00.08 AM.png

 

Let us now construct a class having a public and a public static method as

public class MethodReferenceDemo {
    public void methodReferenceInstance(int age, String someName) {
        System.out.println("methodReferenceInstance -----");
	 String value = someName.concat(" age = ").concat(String.valueOf(age));
	 System.out.println("combined value :: " + value);
    }

    public static void methodReferenceStatic(int someInt, String someString) {
        System.out.println("methodReferenceStatic -----");
	String value = someString.concat(" age =
        ").concat(String.valueOf(someInt));
	System.out.println("combined value :: " + value);
    }
}

Here methods methodReferenceInstance and methodReferenceStatic both have same arguments and return type as that of ICombine’s combine method. So, method reference feature of Java 8, can be used to treat the two methods as ICombine’s object in following manner

ICombine combine;
// without method reference
combine = new ICombine() {
    @Override
    public void combine(int age, String name) {
        System.out.println("without method reference---------");
	String value = name.concat(" age = ").concat(String.valueOf(age));
	System.out.println("combined value :: " + value);
    }
};
combine.combine(40, "Middle age guy");
// with method reference
System.out.println("with method reference-----------");
MethodReferenceDemo demo = new MethodReferenceDemo();
combine = demo::methodReferenceInstance;
combine.combine(100, "Old Guy");
combine = MethodReferenceDemo::methodReferenceStatic;
combine.combine(25, "Young Guy");

So, this is all, in method reference feature of Java 8. Hope , you all clearly understood on how it can be used. Look upon these github samples to know more about it.  In part III, I will simply talk about what changes are to be made in Android , for these features to be used.

Lambda Expressions In Android ( Part I )


One of the many  new features introduced in Java 8, this blog post is focused on lambda expression and method reference. Let’s be clear that Android doesn’t support all the new features of Java 8, but only a subset of new features of Java 8.

So, what is lambda expression then? Before, going into nitty gritty of lambda, let us understand it by an analogy. Lambda is simply a short hand notation. Let us take a scenario. There is a mailman who takes a written command. As per the command, the mailman performs certain task. To save time on writing long commands, both command and mailman is now modified to understand short commands. Take a look at following picture

Screen Shot 2016-09-09 at 1.10.29 PM.jpg

Here, previously the long form As Soon As Possible is now reduced into its short form as ASAP. Under the hood, the mailman interprets ASAP as As Soon As Possible and does the task accordingly. So, the one who is writing the command, it will be easier to write short commands.Under the hood, the whole process works same as before.

So, lambda being a short hand notation, makes the coder easier to write down short codes instead of long ones. Lambda expression is used as a short hand notation for anonymous classes with simple implementation i.e. interface definition with only one method. Rather than getting into jargons and definition, let us illustrate this by a simple example

interface IPrint {
		void printName();
}

And to use, this interface, we need to do

IPrint print;
print = new IPrint() {
   @Override
   public void printName() {
       System.out.println("Print without lambda");
   }
};
print.printName();

During this whole process, the most important part is functional implementation of IPrint  i.e  printName() implementation i.e.

public void printName() {
       System.out.println("Print without lambda");
}

This is simply a function, and in a function the most important part are return type, arguments, block of code

Screen Shot 2016-09-09 at 2.00.12 PM.png

Lambda expression is typically shorthand notation for arguments, code block and return type. Let us assume, that we are now concerned with only important part and now we want to write what is important only and scrap out unnecessary parts. Now constructing the same function in short hand notation ( without any lambda expression)

public void printName() {
       System.out.println("Print without lambda");
}
//it's short hand notation be
void (){
   System.out.println("Print without lambda");
}
//we know that if any function returns something, we need to add return statement
//and any function that doesn't return anything, no return statement
//so again the short hand notation be like
(){
  System.out.println("Print without lambda");
}

At this point, don’t get confused where the function name went and all those stuff, just assume we are very busy coders and we want only important stuff of any function definition. Let us look into more examples

IMG_20160909_144828.jpg

Lambda expression is only concerned with method signature ( arguments) and method implementation ( code block) , and provides the short hand notation based upon that. So, the shorthand notation, with lambda expression would be now

img_20160909_150002

Remember, lambda expression is only for interface having single method, implementation. And in order to write lambda expression, you need to know the interface and its method, and then write the short hand notation based upon it. So our interface IPrint will now become

IPrint print;
//without lambda
print = new IPrint() {
    @Override
    public void printName() {
        System.out.println("Print without lambda");
    }
};
print.printName();
//with lambda
print = () -> System.out.println("Print with lambda");
// or
print = () -> {
    System.out.println("First print with lambda");
    System.out.println("Second print with lambda");
};

Let’s see other implementation, an interface having a return type

interface IPrint {
    String printName();
}
IPrint print;
//without lambda
print = new IPrint() {
    @Override
    public String printName() {
        String value = "Without lambda";
	System.out.println(value + " -------------");
	return value;
    }
};
//with lambda
print = () -> System.out.println("With lambda");
print = () -> {
    String value = "With lambda again";
    System.out.println(value + " -------");
    return value;
};

Another implementation where an interface has arguments and return type

interface IPrint {
    int printName(int age, String name);
}
IPrint print;
//without lambda
print = new IPrint() {
    @Override
    public int printName(int age, String name) {
        System.out.println("Without lambda--------");
	System.out.println("Your name = " + name);
	System.out.println("Your age = " + age);
	return age * 10;
    }
};
//with lambdas
//notice the arguments name can be any and type definition not required
print = (a, b) -> {
    System.out.println("With lambda--------");
    System.out.println("Your name = " + b);
    System.out.println("Your age = " + a);
    return a * 20;
    };

print = (int age, String name) -> {
    System.out.println("With lambda again --------");
    System.out.println("Your name String value = " + name);
    System.out.println("Your age int value = " + age);
    return age * 30;
    };

Remember there is no performance gain by writing short hand notation. Lambda is simply ease of writing codes and is concerned with short hand form of method signature and method implementationscreen-shot-2016-09-09-at-3-19-18-pm

Here is the github link which contains, all the examples mentioned in this blog post. In part II I will talk  about method reference feature of Java 8 and finally how we can use these features in Android.