JavaBeat

  • Home
  • Java
    • Java 7
    • Java 8
    • Java EE
    • Servlets
  • Spring Framework
    • Spring Tutorials
    • Spring 4 Tutorials
    • Spring Boot
  • JSF Tutorials
  • Most Popular
    • Binary Search Tree Traversal
    • Spring Batch Tutorial
    • AngularJS + Spring MVC
    • Spring Data JPA Tutorial
    • Packaging and Deploying Node.js
  • About Us
    • Join Us (JBC)
  • Privacy

Java 8 Lambda Expressions Example

March 30, 2014 by Krishna Srinivasan Leave a Comment

This tutorial highlights the benefits and method of using the Lambda expression which is new Java language feature introduced from Java 8. Lambda expressions are used for executing the methods in the functional interfaces. These are very powerful expressions to reduce the code size in the programming languages. But, it is not yet added as part of the Java language. With Java 8 release, Java programmers are delighted to use this feature.

One of the challenge in the Java code is the instantiate the anonymous classes. The code for using the anonymous class is not very clear and it requires many lines of code. If you look at Java API, there are many interfaces declared with single abstract methods where the implementation done by anonymous way. These type of interfaces are known as the Functional Interfaces.

What is Functional Interface?

With Java 8, a new term “functional interface” is introduced. If an interface contains only one abstract method, then it is known as the functional interface. Prior to Java 8, these interfaces are called as “single abstract method interfaces”. Lambda expression simplifies the way we use the functional interfaces. The following are the few important points about the functional interfaces.

  • Functional interface has only one abstract method
  • @FunctionalInterface annotation can be used for denoting the functional interface. However, it is not necessary to use this annotation, it is only useful to catch the error in the compile time. When you annotate an interface with @FunctionalInterface, if more then one abstract method is defined it will throw a compiler error.
  • Functional interfaces can define one or more default methods.

Lambda Example

FunctionalInterface1.java

[code lang=”java”]
package javabeat.net.core.java8;
@FunctionalInterface
public interface FunctionalInterface1 {
void print();
}
[/code]

FunctionalInterface2.java

[code lang=”java”]
package javabeat.net.core.java8;
@FunctionalInterface
public interface FunctionalInterface2 {
void print(int i);
}
[/code]

Java8LambdaExample.java

If you look at the below code example, the above two functional interfaces are used with the lambda expressions. There are two types of lambda:

  1. Lambda statement : It is a single line expression with out open and close braces.
  2. Lambda Block : It is multiple lines of statements enclosed by the braces.

[code lang=”java”]
package javabeat.net.core.java8;

/**
* Java 8 Lambda Example
* @author krishna
*
*/
public class Java8LambdaExample {
public static void main(String args[]){
// Prior to Java 8 Anonymous class instantiation
new FunctionalInterface1() {
@Override
public void print() {
System.out.println("Prior to Java 8 Anonymous class instantiation");
}
};

// Lambda Expression where no argument in method
FunctionalInterface1 f1 = () -> System.out.println("Lambda Expression with No Method Arguements");

// Lambda Expression where one argument in method
FunctionalInterface2 f2 = (int i) -> {
System.out.println("Lambda Block with Method Arguements");
System.out.println("Parameter Passed : "+ i);
};

f1.print();
f2.print(10);
}
}
[/code]

Output

[code]
Lambda Expression with No Method Arguements
Lambda Block with Method Arguements
Parameter Passed : 10
[/code]

Runnable Lambda

This example shows how to use the Runnable interface as the lambda. Runnable interface has only one abstract method run(), which implies that this is a functional interface. Lets look at the example.
Java8LambdaRunnable.java

[code lang=”java”]
package javabeat.net.core.java8;

/**
* Lambda Runnable Example
* @author krishna
*
*/
public class Java8LambdaRunnable {
public static void main(String args[]) {
System.out.println("=== RunnableTest ===");
Runnable r1 = new Runnable() {
@Override
public void run() {
System.out.println("Hello world one!");
}
};
Runnable r2 = () -> System.out.println("Hello world two!");
r1.run();
r2.run();
}
}
[/code]

Output

[code]
=== RunnableTest ===
Hello world one!
Hello world two!
[/code]

Filed Under: Java Tagged With: Java 8, Project Lambda

Enhanced Collections API in Java 8- Supports Lambda expressions

May 26, 2012 by Mohamed Sanaulla Leave a Comment

Continuing with our exploration of JSR-335 lets look at some of the enhancements to the collections API as part of the Project Lambda effort. A new feature in the language and not supported by the existing API is just not what the programmers would want. And this is what Brian Goetz and his team working on JSR-335 realized. It was not an easy task of enhancing the existing API without breaking uncountable lines of code. That was a challenge which they took up and managed to get around this by introducing the concept of defender methods.

also read:

  • Java 8.0 Tutorials
  • Java 7.0 Tutorials
  • New Features in Java 7.0
  • G1 Garbage Collector in Java 7.0

To outline the major changes in collection API:

  • Support for internal iteration by providing methods like forEach, filter, map and others which are added to the Iterable interface with default implementations (Defender methods).
  • Explicit parallel APIs for greater parallelism support. These can be combined with Fork/Join to divide the tasks
  • Greater stress on immutability and avoiding in-place mutation which was done in the conventional for-each loops

All of these are possible by giving the API/method power to decide its iteration. And the caller would pass in a block of code which would be applied on each of the element or elements decided by the API/method being invoked. That’s pretty much of the theory, lets see it in action on a List of integers from 1 to 10.
[code lang=”java”]
List<Integer> counts = new ArrayList<Integer>;();
for(int i=1;i <= 10; i++){
counts.add(i);
}
[/code]

Iterating through the elements in the list:
[code lang=”java”]
//Using external iterators
System.out.println(‘Using external iterator’);
for(Integer i : counts){
System.out.print(i+’ ‘);
}
System.out.println();
[/code]
versus
[code lang=”java”]
//Using internal iterators
System.out.println(‘Using internal iterator’);
//Passing a code block to forEach method
counts.forEach(i -> {System.out.print(i*2+’ ‘)});
System.out.println();
[/code]
Very concise right? Digging into forEach method introduced in Iterable interface, it is implemented as:
[code lang=”java”]
void forEach(Block<? super T> block) default {
Iterables.forEach(this, block);
}
[/code]
if you are confused about the use of “default” keyword, then please read about it here. Iterables is a new class to be introduced in Java 8 and the forEach method in Iterables expects an collection/something which can be iterated and the block of code to apply on the each element iterated, the implementation is:
[code lang=”java”]
public static <T> Iterable<T>
forEach(final Iterable<? extends T> iterable,
final Block<? super T> block) {
Objects.requireNonNull(iterable);
Objects.requireNonNull(block);
for (T each : iterable) {
block.apply(each);
}

return (Iterable<T>) iterable;
}
[/code]
Looks like forEach method does nothing different from the older for-each loop, that’s how forEach ought to work. If you want to maintain immutability you can use a different method which I will write a little later. But for now, forEach iterates through the iterable and applies the block to each of the element. Going into the Block and apply method would be out of scope of this article, lets look at it in a different article.

Lets explore a bit further and print all the even elements of the list.
Using external iteration ( for-each loop) we would have
[code lang=”java”]
for ( Integer i : counts){
if ( i % 2 == 0 ){
System.out.print(i+’ ‘);
}
}
[/code]
and using the new APIs:
[code lang=”java”]
//filter evaluates the block
//and returns a new iterable.
counts.filter(i -> i%2 == 0)
.forEach(i-> {System.out.print(i+’ ‘);});
[/code]
the filter method doesn’t create a new collection instead it creates a new Iterable. The difference it makes is that there is no intermediate collection created after filter is invoked.

Another example before we close- lets multiply all the odd elements by 2 and create a new list.
Using the for-each loop, this can be done as:
[code lang=”java”]
List<Integer> newCounts = new ArrayList<Integer>();
for(Integer i : counts){
if ( i % 2 != 0 ){
newCounts.add(i*2);
}
}
for(Integer i : newCounts){
System.out.print(i+’ ‘);
}
[/code]
and the same using new API:
[code lang=”java”]
List<Integer>; newCountsNew = new ArrayList<Integer>;();
counts.filter(i -> i % 2 != 0)
.map(i -> i*2)
.into(newCountsNew);
newCountsNew.forEach(i -> {System.out.print(i+’ ‘);});
[/code]
Apart from the other benefits mentioned at the beginning the above code which uses new APIs is more readable than the one which uses for-each.

If you want to read more about the state of the APIs with respect to the lambda expressions, please do so here.
The examples used above can be found here as well.

Filed Under: Java Tagged With: Java 8, Project Lambda

Lambda Expressions in Java 8

May 21, 2012 by Mohamed Sanaulla Leave a Comment

Mike Duigou announced here that the Iteration 1 of Lambda Libraries is complete which includes support for defender methods, enhancement of the collection apis among other changes.

also read:

  • Java 8.0 Tutorials
  • Java 7.0 Tutorials
  • New Features in Java 7.0
  • G1 Garbage Collector in Java 7.0

Before proceeding further its good to read about Functional Interfaces and Defender Methods to some extent.

Lets dive into an example, consider sorting of Person objects where each Person would have firstName, lastName, dateOfBirth, placeOfBirth

[code lang=”java”]
class Person {

public Person(String fName,
String lName,
Date dob,
String place)
{
firstName = fName;
lastName = lName;
dateOfBirth = dob;
placeOfBirth = place;
}

@Override
public String toString(){
return firstName+" "+lastName;

}
String firstName;
String lastName;
Date dateOfBirth;
String placeOfBirth;
}
[/code]

Lets see how we can sort this with and without using lambda expressions

[code lang=”java”]
public class LambdaBasicDemo {

public static void main(String[] args) {
List<Person> people = createPeople();

// Sorting pre Lambda Expression era
//Sorting by firstName
Collections.sort(people,new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
return o1.firstName.compareTo(o2.firstName);
}
});
System.out.println("Firstname sort: "+people);

//Sorting using Lambda expressions and updated collection API
//Sorting by lastName
people.sort((o1,o2) -> {
return o1.lastName.compareTo(o2.lastName);
});
System.out.println("Lastname sort:" +people);

}

static List<Person> createPeople(){
Calendar calendar = Calendar.getInstance();
calendar.set(1900, Calendar.JANUARY,01,12,00);
List<Person> people = new ArrayList<>();
Person person = new Person("Raju","Sarkar",calendar.getTime(),"Delhi");
people.add(person);

calendar.set(1950,Calendar.JUNE,30,12,30);
person = new Person("Anant","Patil", calendar.getTime(),"Pune");
people.add(person);

calendar.set(1950,Calendar.DECEMBER,30,12,30);
person = new Person("Danny","Great", calendar.getTime(),"London");
people.add(person);

return people;
}
}
[/code]

The output would be:

[shell]
Firstname sort: [Anant Patil, Danny Great, Raju Sarkar]
Lastname sort:[Danny Great, Anant Patil, Raju Sarkar]
[/shell]

You all are aware of how the collections are sorted using the Collection API and Comparator so I am not going into that. There’s an interesting syntax which uses a dash(-) and an greater than symbol(>) [dash-rocket], lets look into a bit of detail about this syntax:

[code lang=”java”]
//Sorting using Lambda expressions and updated collection API
//Sorting by lastName
people.sort((o1,o2) -> {
return o1.lastName.compareTo(o2.lastName);
});
[/code]

There obvious difference between the verbosity of the code for sorting by creating anonymous inner class and by using Lambda expressions. The Lambda expression consists of lambda parameters and Lambda body. A Lambda expression is represented as () -> {} where () contains the lambda parameters and the {} contains the lambda body. A lambda expression can be void returning or value returning i.e can return nothing or return result of some expression.

In the above example, we are constructing a lambda expression for the functional interface Comparator with a functional descriptor (T o1, T o2) -> int.

Note: Something interesting to note here is that with Java 8 the Comparator interface has 2 more methods

[code lang=”java”]
Comparator<T> reverse() default {
return Collections.reverseOrder(this);
}
Comparator<T> compose(Comparator<? super T> other) default {
return Comparators.compose(this, other);
}
[/code]

We would like to keep this confusion aside for time being and I will get back on this and explain as to why and how the defender methods are not considered. If someone if aware of the reason, please add them as comments.

Digging deeper into the lambda expression, the (o1, o2) indicates the lambda parameters. The type information for o1 and o2 are inferred from the context in which it is being used, and in our case they are of type Person. The {return o1.lastName.compareTo(o2.lastName);} is the lambda body.

Advantages of using Lambda expressions over Anonymous inner class approach:

  • Lambda expressions are lighter on code than the anonymous inner classes.
  • An advantage of using Lambda expressions is the resolution of this and super when used within the Lambda expression. In case of anonymous inner class approach the this and super are resolved to the anonymous inner class. And this is not at all useful because there’s nothing that one would want from the anonymous inner class. But in case of lambda expressions these resolve to the enclosing class.
  • Permissibility of use of effectively final variables in lambda expressions, where as only final variables can be used in local inner classes

Interestingly, compiling LambdaBasicDemo.java gives 3 class files (apart from Person.class): LambdaBasicDemo.class, LambdaBasicDemo$1.class, LambdaBasicDemo$2.class.

  • LambdaBasicDemo.class corresponds to the public class LambdaBasicDemo.
  • LambdaBasicDemo$1.class corresponds to the anonymous inner class for Comparator
  • and LambdaBasicDemo$2.class corresponds to the lambda expression. So under the hood, the compiler wraps this lambda expression with a new class and then instantiates the same.

That’s pretty much it for a sneak peak. Stay tuned for lot more as I continue to explore the feature.

Filed Under: Java Tagged With: Java 8, Project Lambda

What are Functional Interfaces and Functional Descriptor?

May 20, 2012 by Mohamed Sanaulla Leave a Comment

There is no Java developer who is not familiar with these Interfaces which contain only one method. If you are not familiar, no worries I will in the course of this article throw some light on such interfaces.

also read:

  • Java 8.0 Tutorials
  • Java 7.0 Tutorials
  • New Features in Java 7.0
  • G1 Garbage Collector in Java 7.0

Those who have created GUI applications using Swing/AWT would be familiar with ActionListener interface, those working on mutli threaded applications or concurrent applications would be familiar with Runnable, Callable, Executor and other interfaces. Those who worked on sorting of objects would be familiar Comparator interface. What is it that is common between them? Yes, you got it right, they are interfaces with one method (not considering the methods it inherits from the Object class). These were called Single Abstract Method classes, its were because with Java 8 these are called as Functional Interfaces.

Runnable:

[code lang=”java”]
public interface Runnable {
public abstract void run();
}
[/code]

Callable:

[code lang=”java”]
public interface Callable<V> {
V call() throws Exception;
}
[/code]

Executor:

[code lang=”java”]
public interface Executor {
void execute(Runnable command);
}
[/code]

Functional Interfaces can also have abstract methods which are inherited from Super interfaces and those should be override equivalent (read more about override equivalent methods here). For example:

[code lang=”java”]
interface I1{
void method1(List<Number> n);
}
interface I2{
void method1(List n);
}
interface I3 extends I1, I2{} // Valid Functional Interface.
interface I4{
int method1(List n);
}
interface I5 extends I2,I4{} //Not a functional interface
[/code]

The bottom line is that functional interfaces are those that have single abstract methods (apart from the inherited public methods from Object class). The single method might not be the only method, but can be inherited from multiple interfaces but they signatures are equivalent to each other (See Override equivalent) such that those multiple methods actually represent/act as a single method.

Along with the functional interfaces, there’s a concept called functional descriptors associated. Functional descriptor of an Interface is the method type of the single abstract method of the interface. Here the method type of a method includes: argument types, return type and the throws clause.
In our above examples the functional descriptors are

[code lang=”java”]
//For Runnable
() -> void
//For Executor
(Runnable) -> void
//For Interface I3
(List<String>) -> void
[/code]

These concepts are used while constructing lambda expressions and using them. Just to give a brief: all these functional interfaces can be represented by using Lambda expressions, the compiler in turn infers the context in which the lambda expression is used and uses the corresponding Functional Interface.

Filed Under: Java Tagged With: Java 8, Project Lambda

Use of Virtual Extension methods in the Java 8 APIs

May 18, 2012 by Mohamed Sanaulla Leave a Comment

In wrote a bit about Virtual extension methods here and here. I thought of going over this implementation in the JDK, so that it will give us an idea of how these can be applied.

also read:

  • Java 8.0 Tutorials
  • Java 7.0 Tutorials
  • New Features in Java 7.0
  • G1 Garbage Collector in Java 7.0

As I told earlier, the main intention of adding the virtual extension methods was to provide an option to extend the existing interfaces (by adding new methods) without breaking the existing usages. Consequently the main contender for this is the Collection interface in java.util package. All the collection classes in Java implement this interface. Few methods were added to the Collection interface to provide support for the new collections API.

Lets consider the retainAll method as defined below (copied as is from the source distributed with the JDK):

[code lang=”java”]
/**
* Retains all of the elements of this collection which
* match the provided predicate.
*
* @param filter a predicate which returns {@code true}
* for elements to beretained.
* @return {@code true} if any elements were retained.
*/
// XXX potential source incompatibility with retainAll(null)
// now being ambiguous
boolean retainAll(Predicate<? super E> filter) default {
return CollectionHelpers.retainAll(this, filter);
}
[/code]

New CollectionHelpers class is introduced which contains the implementation of various methods used as virtual extension methods. Also notice that the method in the Collection interface doesn’t have any code/implementation details, instead they refer to methods from another class (CollectionHelpers in this case).

The CollectionHelpers.retainApp is defined as (From the source for CollectionHelpers):

[code lang=”java”]
public static <E> boolean retainAll(Collection<E> collection,
Predicate<? super E> filter ) {
boolean retained = false;
Iterator<E> each = collection.iterator();
while(each.hasNext()) {
if(!filter.test(each.next())) {
each.remove();
} else {
retained = true;
}
}
return retained;
}
[/code]

There are numerous such examples in the JDK 8, and one can explore different options from the source for the Java APIs.

Filed Under: Java Tagged With: Java 8, JavaFX, Project Lambda

Resolution of the invocation of Virtual Extension Methods in Java 8

May 17, 2012 by Mohamed Sanaulla Leave a Comment

There is a list of method resolution approach for virtual extension methods explained here. One of the interesting ones is when a class implements multiple interfaces and say 2 of the interfaces have same method signature but different implementations.

also read:

  • Java 8.0 Tutorials
  • Java 7.0 Tutorials
  • New Features in Java 7.0
  • G1 Garbage Collector in Java 7.0

But before that, lets look at a case where the class implements an interface, say I1 and I1 in turn extends another interface I2 and both I1 and I2 have a method with exact same signature. How is the method invocation using the instance of the implementing class handled?
For this lets look at the following example:

[code lang=”java”] public class DefenderMethodsResolution{
public static void main(String[] args){
MySuperClass obj = new MySuperClass();
System.out.println(obj.findProduct(4,5));
}
}
class MySuperClass implements SpecialMathOperator{

}

interface SpecialMathOperator extends MathOperator{
public int findProduct(int a, int b) default{
return MathOperatorHelper.findProductUsingSum(a,b);
}
}
interface MathOperator{
public int findProduct(int a, int b) default{
return MathOperatorHelper.findProduct(a,b);
}
}
class MathOperatorHelper{
public static int findProduct(int a, int b){
System.out.println("Finding product by multiplying");
return a*b;
}

public static int findProductUsingSum(int a, int b){
int product = 0;
System.out.println("Finding product by iterative sum");
for (int i=0;i < b; i++){
product += a;
}
return product;
}
}
[/code]

The output for the above is:

[shell]
javac DefenderMethodsResolution.java
java DefenderMethodsResolution
Finding product by iterative sum
20
[/shell]

It clearly shows that in this case the method resolution is handled by neglecting the super Interface and considering the more specific sub Interface provided sub interface is overriding (I dont know the exact term to use here) the method.

When one thinks of Interfaces having code, then the first thing that comes to the mind is “Deadly Diamond of Death“. Lets see how this is tackled by the compiler. Lets go ahead and slightly edit the code to remove the extends from the SpecialMathOperator interface and make MySuperClass implement both the interfaces. [I know this is not the very best examples, but I think good enough to explain the concept?]

[code lang=”java”]
public class DefenderMethodsResolution{
public static void main(String[] args){
MySuperClass obj = new MySuperClass();
System.out.println(obj.findProduct(4,5));
}
}
class MySuperClass implements SpecialMathOperator,MathOperator{

}

interface SpecialMathOperator {
public int findProduct(int a, int b) default{
return MathOperatorHelper.findProductUsingSum(a,b);
}
}
interface MathOperator{
public int findProduct(int a, int b) default{
return MathOperatorHelper.findProduct(a,b);
}
}
class MathOperatorHelper{
public static int findProduct(int a, int b){
System.out.println("Finding product by multiplying");
return a*b;
}

public static int findProductUsingSum(int a, int b){
int product = 0;
System.out.println("Finding product by iterative sum");
for (int i=0;i < b; i++){
product += a;
}
return product;
}
}
[/code]

Trying to compile the above code we would get:

[shell]
$javac DefenderMethodsResolution.java

javaDefenderMethodsResolution.java:4: error:
reference to findProduct is ambiguous,
both method findProduct(int,int) in MathOperator
and method findProduct(int,int) in SpecialMathOperator match
System.out.println(obj.findProduct(4,5));
^
DefenderMethodsResolution.java:7: error:
class MySuperClass inherits unrelated defaults for findProduct(int,int)
from types SpecialMathOperator and MathOperator
class MySuperClass implements SpecialMathOperator,MathOperator{
^
2 errors
[/shell]

So the compiler doesn’t allow the compilation of such code thereby eliminating the Deadly Diamond of Death problem.

Filed Under: Java Tagged With: Java 8, Project Lambda

Virtual Extension Methods(or Defender Methods) in Java 8

May 16, 2012 by Mohamed Sanaulla Leave a Comment

As part of the JSR-335 (Project Lambda) which adds closure support to Java language, there were quite a few changes in the language to support the use of closures in the existing Java APIs (Collection APIs to a large extent). One such change is the introduction of Virtual Extension Methods.

also read:

  • Java 8.0 Tutorials
  • Java 7.0 Tutorials
  • New Features in Java 7.0
  • G1 Garbage Collector in Java 7.0

We all are aware of the fact that the interfaces don’t contain any implementation for the methods. To provide support for new APIs which support the use of closures and also which can run on Multi core platforms there has to be some way to add these APIs to existing classes. For example, methods like forEach, map, reduce, filter which act on a collection can be added to the Collection class directly or create a new interface and let all the collection API implement them or leave it to the user of the API to implement the new interface. The first 2 approaches would lead to breaking lots of existing code because of the lack of implementation of these new methods in the interface. The last approach is possible, but it doesn’t enhance the collection API out of the box.

The team which handles JSR-335 thought of a way to add default implementation to the interfaces, which gives an option for the implementor to override the method or to leave it as is. This way new APIs can be added to the Collection class without breaking the existing code and yet provide the full support of the closures to the existing code. One can read in depth about Virtual Extension Methods here.

Lets see an example of a virtual extension method:
[code lang=”java”]
interface TestInterface{
public void testMe();

public void aDefaulter() default{
System.out.println("Default from interface");
}
}
[/code]
Using the “default” keyword we can add new methods to the existing interface and allowing the implementing classes to use this default implementation if they don’t override. Something like:
[code lang=”java”]
public class DefenderMethods{
public static void main(String[] args){
InterfaceImplementer imp = new InterfaceImplementer();
imp.testMe();
imp.aDefaulter();
}
}
class InterfaceImplementer implements TestInterface{
public void testMe(){
System.out.println("Hello World!");
}
}
[/code]

The output for above program would be:
[shell]
~/javaP/java8$ javac DefenderMethods.java
~/javaP/java8$ java DefenderMethods
Hello World!
Default from interface
[/shell]

Moving further, we can override the aDefaulter method in its implementing class, something like
[code lang=”java”]
class InterfaceImplementer implements TestInterface{
public void testMe(){
System.out.println("Hello World!");
}

public void aDefaulter(){
System.out.println("Defautler overridden from class");
}
}
[/code]
for which the output will be:
[shell]
~/javaP/java8$ javac DefenderMethods.java
~/javaP/java8$ java DefenderMethods
Hello World!
Defautler overridden from class
[/shell]

The bytecode generated for the DefenderMethods class still uses invokevirtual opcode for invoking the default method, which indicates its treated like any other usual interface method in its invocation.

There’s lot more to this concept like overriding rules, method invocation rules which I would like to cover in subsequent posts. And also sample code from the JDK 8 which uses this feature.

Filed Under: Java Tagged With: Java, Java 8, Project Lambda

Using Lambda Expressions of Java 8 in Java FX event handlers

May 14, 2012 by Mohamed Sanaulla Leave a Comment

Note: The Project Lambda (JSR-335) to be added in Java 8 is evolving and the sample here is how one can use Lambdas with the current Java8 build downloaded from here. I will try to update the sample if there are any changes in the API in future.

also read:

  • Java 8.0 Tutorials
  • Java 7.0 Tutorials
  • New Features in Java 7.0
  • G1 Garbage Collector in Java 7.0

I thought it will be good to get a peak of how Lambda Expressions can be used with JavaFX or for that matter any Single Abstract Method (SAM) types.

Lets build a sample with just one toggle button and change the text of the toggle as and when it is selected/un-selected.

The code with the current Java -7 version would be:
[code lang=”java”]
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.ButtonBase;
import javafx.scene.control.ToggleButton;
import javafx.scene.control.ToggleButtonBuilder;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

public class LambdasWithJavaFx extends Application {
public static void main(String[] args){
Application.launch(args);
}
@Override
public void start(Stage stage) throws Exception {
BorderPane root = new BorderPane();
ToggleButton button = new ToggleButton("Click");

final StringProperty btnText = button.textProperty();
button.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent actionEvent) {
ToggleButton source = (ToggleButton) actionEvent.getSource();
if (source.isSelected()) {
btnText.set("Clicked!");
} else {
btnText.set("Click!");
}
}
});

root.setCenter(button);

Scene scene = new Scene(root);
stage.setScene(scene);
stage.setWidth(200);
stage.setHeight(200);
stage.show();
}
}
[/code]

The main focus would be on the EventHandler set for the ToggleButton, henceforth I would just show that part of the above code.

Lets see how we can use the Lambda expression to update above code.
[code lang=”java”]
button.setOnAction((ActionEvent event)-> {
ToggleButton source = (ToggleButton) event.getSource();
if (source.isSelected()) {
btnText.set("Clicked!");
} else {
btnText.set("Click!");
}
});
[/code]

The only method in the EventHandler class is the handle(Event event) method and in the above example we just write the body and the parameter declaration for the method and remove all the unnecessary instantiation code.

We can remove the type declaration for the event, as the compiler will infer the type from the context. The context here is the Action event and hence the EventHandler expects a ActionEvent and thereby the event reference is inferred to be of ActionEvent type.
[code lang=”java”]
button.setOnAction((event)-> {
ToggleButton source = (ToggleButton) event.getSource();
if (source.isSelected()) {
btnText.set("Clicked!");
} else {
btnText.set("Click!");
}
});
[/code]

This is just a peek at the Lambda expressions to be introduced in Project Lambda (JSR-335). I would take some time to dive a bit into detail of Lambda expressions.

Filed Under: Java Tagged With: Java 8, Java FX, Project Lambda

Follow Us

  • Facebook
  • Pinterest

As a participant in the Amazon Services LLC Associates Program, this site may earn from qualifying purchases. We may also earn commissions on purchases from other retail websites.

JavaBeat

FEATURED TUTORIALS

Answered: Using Java to Convert Int to String

What is new in Java 6.0 Collections API?

The Java 6.0 Compiler API

Copyright © by JavaBeat · All rights reserved