Lambda expressions
Introduction
Java as a programming language has evolved continuously over various versions adding new features like Swing, NIO, Annotations, Generics, Auto-boxing, Java FX and the latest Java 8 has introduced the much awaited very important feature Lambda expressions.
The typical usage of several interfaces like ActionListener, Runnable etc. were as anonymous classes inside the code where it is used. One single alternative to writing an anonymous class would have been writing a separate class for each interface thus increasing the number of classes. If you look closely at each of these interfaces there is only a single method inside each of these interfaces. Lambda expression provides a very clear and concise way to represent one method interface using an expression. Along with Java 8, an interface like ActionListener, Runnable that follows this pattern is called as a “Functional Interface“.
Let us Dig further
The following table depicts the composition of a Lambda expression:
Let us have a look at the examples using the above parts in the following picture:
Lambda expressions reduces the number of lines of code which are required in case of anonymous classes. Let us run through a quick example of the ActionListener using Anonymous class and make the code shorter using Lambda expression.
As you can see from the class above the five lines of code for adding an anonymous class is done in just one line of code. When the program and click the check button following output is seen on your console:
Note: In the above scenario lambda expression is also passed as a parameter.
Java 8, comes with a set of standard functional interfaces and is part of java.util.function package. Out of these standard functional interfaces let us understand the Predicate interface which is as below:
public interface Predicate<T>{
public boolean test(T t);
}
The test method takes a generic class and returns a boolean result.
Consider one example in which you have to place an order for items whose quantity is less than or equal to 10. Prior to Java 8, one would hard code the comparison inside the method while iterating over the collection of items. Using Lambda expressions functional interface Predicate life becomes easier as seen below in the code example.
Consider the class Item.java
import java.util.List;
import java.util.ArrayList;
public class Item {
private Item(Item.Builder builder){
id = builder.id;
qty = builder.qty;
itemName = builder.itemName;
}
private Item(){
super();
}
private long id;
private String itemName;
private int qty;
public long getId(){
return id;
}
public int getQty(){
return qty;
}
public String getItemName(){
return itemName;
}
public void setId(long id){
this.id = id;
}
public void setQty(int qty){
this.qty = qty;
}
public String setItemName(String itemName){
return itemName;
}
public static List<Item> createItemList(){
List<Item> items = new ArrayList<Item>();
items.add(
new Item.Builder()
.id(1)
.itemName("Screw")
.qty(10)
.build() );
items.add(
new Item.Builder()
.id(2)
.itemName("Bolt-12")
.qty(9)
.build() );
items.add(
new Item.Builder()
.id(3)
.itemName("Bolt-14")
.qty(12)
.build() );
for(Item i : items){
System.out.println(i.getItemName());
}
return items;
}
public static class Builder{
private long id = 0;
private String itemName = "";
private int qty = 0;
public Item.Builder id(long id){
this.id = id;
return this;
}
public Item.Builder itemName (String itemName){
this.itemName = itemName;
return this;
}
public Item.Builder qty(int qty){
this.qty = qty;
return this;
}
public Item build(){
return new Item(this);
}
}
}
Now let us code the OrderManager class in which there is a method for ordering the items if they lie below or equal to the required quantity.
import java.util.*;
import java.util.function.Predicate;
public class OrderManager{
public void placeOrder(List<Item> items, Predicate<Item> pred){
for(Item item: items){
if(pred.test(item)){
System.out.println("Place order for item : " + item.getItemName());
}
}
}
}
The class PredicateTest.java for passing the predicate to the reorder method.
import java.util.List;
import java.util.function.Predicate;
public class PredicateTest {
public static void main(String[] args){
List<Item> items = Item.createItemList();
OrderManager mgr = new OrderManager();
Predicate<Item> reorder = i -> i.getQty() <= 10;
mgr.placeOrder(items, reorder);
}
}
Finally, the output on the console:
The output seen above shows that we have to place the order for item Screw and Bolt-12.
Following are some set of standard interfaces which also has a primitive version.
Consumer
: An action to be performed with the object passed as argument
Function
: Transform a T to a U
Supplier
: Provide an instance of a T (such as a factory)
UnaryOperator
: A unary operator from T -> T
BinaryOperator
: A binary operator from (T, T) -> T
In this part it might have become clear about the Lambda expressions syntax, Lambda expressions will replace anonymous inner classes, and Predicate used for checking or testing on a list. In the next tutorial we will cover a bit further on Lambda expressions and its usage on collections.
Happy Learning!!!