Hello world!
In this post, we’ll explore Programming with Java 8. To begin with, I’ll talk about Lambda expression, a key feature of Java 8. Lambda expressions facilitate functional programming into Java. In Java, anonymous inner classes provide a way to implement classes that may occur only once in an application. By creating the class in place, where it is needed, the code is a little easier to read. Anonymous classes enable you to make your code more concise. They enable you to declare and instantiate a class at the same time. The code is not elegant because quite a bit of code is required just to define one method.
What is a Functional Interface?
In a single line description, interface with only abstract method is referred as Functional Interface. However, a functional interface can have more than one static or default methods, and also can Override some methods from java.lang.Object
Luckily enough, you do not need to verify the Functional Interface, Compiler will do it for you. But you can specify @FunctionalInterface annotation to reduce its workload.
Here’s an example.
1 2 3 4 5 6 7 8 9 10 11 12 |
@FunctionalInterface interface FuncInterface{ // Only abstract method. void first(Collection collection); // Functional interface can have more than one static or default methods. default void second() { System.out.println("This is default in Functional Interface."); } // And also can override methods of java.lang.Object @Override public String toString(); } |
Some frequently used and popular functional interfaces are:
- java.awt.event.ActionListener;
- java.lang.Runnable
- java.util.Comparator
Vertical Problem
The main problem with Anonymous classes is the syntax. For some simple operations, we need to write additional syntactical code each time. The problem of bulky syntax is referred as a “Vertical problem” by Java people.
The structure of Lambda expression:
Lambda expression’s syntax can be divided into three parts.
- Arrow (->) token
- Argument List
- A lambda expression can contain zero or more arguments.
- No argument.
123() -> {System.out.println("No argument statement");} - Single argument.
123(int arg) -> {System.out.println("Single argument : " + arg);} - More than one arguments.
123( int arg1, String arg2 ) -> {System.out.println("Two arguments : " + arg1 + " and " + arg2);} - You can eliminate the argument type while passing it to lambda expressions, those are inferred types. i.e. (int a) and (a) — both are same.
- More than one argument are separated by a comma (,) operator.
- You can also eliminate “()” if there is only argument to avoid Horizontal Problem.
- ( arg ) -> {…} can be written as arg -> {…}
- You cannot use inferred and declared types together. The following is invalid.
- Example:
- (int arg1, arg2) // This is invalid
- The body of a Lambda expression:
- The body can be a single expression or a statement block.
- If a body contains only single expression then the expression will be simply evaluated and returned.
-
1() -> System.out.println("No argument");
- If a body is a statement of the block, then it will be evaluated same as a method body, that will be called and a hidden return statement at the end block that will return control to the caller after execution of the block. So, branching statements ( continue and break ) are illegal and return is not necessary to write.
-
1234() -> {System.out.println("Bad lambda");break ; // this statement is not allowed here.}
How to use Lambdas?
Let’s look into another example.
1234567891011121314151617181920212223242526 public class Lambda_Expression {public static void main(String args[]){Lambda_Expression example = new Lambda_Expression();//declarationCompute addition = (int a, int b) -> a + b;//with out type declarationCompute subtraction = (a, b) -> a - b;System.out.println("10 + 5 = " + tester.operate(10, 5, addition));System.out.println("10 - 5 = " + tester.operate(10, 5, subtraction));//with parenthesisGreet anyone = message ->System.out.println("Hello World");//without parenthesisGreet someone = (message) ->System.out.println("Hello------ " + message);someone.sayMessage("Nadeeshani");}interface Compute {int operation(int a, int b);}interface Greet {void say(String message);}private int operate(int a, int b, Compute compute){return compute.operation(a, b);}}
Here are a few conclusions from the above code:
- We have written our own behaviour for every anonymous class methods.
12 Compute addition = (int a, int b) -> a + b; //behaviour 1Compute subtraction = (a, b) -> a - b; // behaviour 2
//In the type is also avoided
2. We are passing the behaviour along with values.
1 System.out.println("10 + 5 = " + tester.operate(10, 5, addition));
Tester.operate is the method in the Great interface which has the 3 parameters. We are passing the behaviour of type Compute.
3. Based on the behavior, the actions will be performed.
When to use Lambdas?
It is a use case of the Lambda expression that code running the code only when necessary.
There are many reasons for executing code later, such as
- Running the code in a separate thread
- Running the code multiple times
- Running the code at the right point in an algorithm (for example, the comparison operation in sorting)
- Running the code when something happens (a button was clicked, data has arrived, and soon)
- Running the code only when necessary
I hope this got you a good head start with programming in Java 8, especially how and when to use Lambda expressions and. I’ll be back with more soon.