Java Lambdas, SAMs And Events
Java Lambdas, SAMs And Events
Written by Ian Elliot   
Tuesday, 14 November 2017
Article Index
Java Lambdas, SAMs And Events
Event Handling & Closure
Anonymous Classes

What is all the fuss about Java lambdas? Easy - they make passing functions to other functions much easier. In particular they make setting up event handlers in GUIs such as Swing fairly simple even if you can't always make use of them. This is the easy guide to lambdas. 

Modern Java
With NetBeans And Swing

covericon

Contents

  1. Getting started with Java

    In chapter 1 we tell you how to get started with modern Java development in the shortest possible time. The approach uses NetBeans and Swing and all of the resources used are free to download and use.

  2. Introducing Java - Swing Objects
    In the second chapter of our beginner's guide to Modern Java we find out more about objects by exploring the Swing framework with a simple hands-on example.

  3. Writing Code

    Using ifs and loops is one of the most difficult parts of learning how to program. Our beginners introduction to Java reaches the part all programmers have know and know well - how to write code.

  4. Command Line Programs
    Command line programming means doing things in the simplest possible way. We take a careful look at how data types and code build a program.

  5. User Interface - More Swing
    Finding out how to create a User Interface (UI) using the Java Swing library is not only a useful skill, it also is an ideal way to learn about objects and to make sure that the ideas really have sunk in.

  6. Working With Class
    The Swing components have provided an easy approach to the idea of objects, but there comes a time when you have to find out how to create your own. In this part of Modern Java, we look at the standard ideas of object-oriented programming.

  7. Java Class Inheritance
    Working with classes and objects is a very sophisticated approach to programming. You can't expect to absorb all of its implications in one go. We have already looked at the basics of class and objects. Now we need to look at encapsulation, constructors, overloading and inheritance.

  8. Java Data Types - Numeric Data 
    After looking at some of the advanced ideas of classes and objects we need to return to some simpler topics to make our understanding complete. We need to look more closely at data and, to get things moving, numeric data. 

  9. Java Data Types - Arrays And Strings
  10. Building a Java GUI - Containers
    In this chapter we get to grips with the idea of a container that is used to host components to build a user interface. We also find out how the Swing GUI Builder generates code to make it all much easier. 
  11. Advanced OOP - Type, Casting, Packages
  12. Value And Reference 
  13. Java Lambdas, SAMs And Events

 

As long as you can use Java 8 then you can use lambdas.

The latest versions of NetBeans and IntelliJ do a good job of supporting them out of the box so why not use them?

The very first thing to say is that Java lambdas are not like other lambdas.

They aren't the pure creation of a purpose built language but the best that can be done to implement something like a lambda within the existing Java way of doing things. However rather than criticise the Java lambda you should marvel at the clever way it has been integrated into what already existed.

First what is a lambda?

Everything in Java is an object and the only way a function can exist is as a method, i.e. as part of an object. Java 8 changed all of this with the introduction of lambda functions.

A lambda function is a function that doesn’t belong to an object.

That is, it isn’t a method and it can be passed as a parameter to another function. 

This is useful in all sorts of contexts, but it is particularly useful if you are programming in a GUI framework that uses events. An event handler is just a function that is called when the event occurs, but because every function in Java has to be a method of some object, before lambdas you had to pass a complete object that had the function as a method. Lambdas simplify event handling for one.

Creating a lambda

In Java 8 and later a lambda is a function that you can define using special notation.

The function doesn’t have a name, it is an anonymous function.

A lambda can also be stored in a suitable variable and passed to another function as a parameter.

You define a lambda by supplying a head with parameters and a body with code:

(parameter list) -> {

   code
   return something;
};

For example:

(a,b)->{
  return a+b;
}

If you are a long time Java programmer what will be most shocking, apart from the fact that this is a function that doesn't belong to an object, is that there are no type specifiers in this declaration. Don’t worry, a lambda expression is strongly-typed but the compiler infers the type of the parameters and the return type from the context.

The point is that lambda expressions are always passed as a parameter or assigned to a variable and it is the type of the parameter or variable that determines the types used in the lambda.

It is not an error to include the data type of the parameters, and you can do it if you think it makes things clearer, but it is always unnecessary.

For example, you could write:

(int a, int b)->{
            return a+b;
}

There are a few simplifications to the lambda notation.

If there is just a single parameter you can omit the parenthesis.

For example:

n ->{
     return -n;
}

If the body is a single expression you can omit the brackets and the return and the result of the expression will be automatically returned.

For example:

n -> -n;

defines the same function as given above or

(a,b)-> a+b;

If you use a return then you need the brackets.

These rules can make lambda expressions look very strange in your code and this might make it harder to read.

Don’t go for the shortest and most compact expression make sure your code is easy to understand.  

Lambda Types

You can’t actually use the lambdas that have been given in the previous section because they don’t have a target type which allows the compiler to work out the type of their parameters etc.

You can't even use them if you supply the parameter types because the lambda as a whole has to have a type not just the parameters.

The problem is that there is no function type in Java.

This goes back to the everything is an object and functions only exist as methods of objects philosophy.

In place of a function type we make use of what is often called a SAM – or a Single Abstract Method.

An interface with a single method defined is a SAM and you can regard it as defining the type of a function i.e. the single abstract method that it defines.

For example:

public interface Sum{
        int sum(int a, int b);
}

This is a SAM for the function sum which takes two ints and returns an int.

Notice that this is not the most direct way to define a function type because you have to define an object type i.e. the Interface Sum and then a method within it i.e. the sum function. This results in more code than is strictly necessary and a duplication of names - what do you call the interface and what do you call the function?

To use the SAM you have to create an instance of it and to do this you have to create a class that implements the interface and more specifically the function. This is even more code and the whole point of a lambda is avoiding having to create this code. 

A lambda expression is just a way of creating an instance of a SAM without having to create a class and then an instance.

For example:

   Sum adder = (a,b)->{
            return a+b;
        };

The lambda expression has its type inferred from the types in the target SAM. That is a and b are ints and the return type is an int. The connection between the lambda and the SAM goes even deeper. The lambda actually creates an object of the type Sum with the abstract method defined by the body of the lambda. 

That is even a lambda function is actually a method of some object.

What this means is that if you want to call the function defined by they lambda you have to write:

int ans=adder.sum(1,2);

That is adder is an instance of the Sum interface with the lambda function as the implementation of its sum function. 

As I said at the beginning Java lambdas are not like other lambdas - they are not pure detached functions, they are still methods that belong to objects. 

This seems confusing at first but Java hasn’t given up the use of SAMs it has simply added lambdas as an easy and more direct way of creating an instance of a SAM.

Most of the time you can ignore the SAM that the lambda is implementing because it is generally predefined for you.

The existing libraries are all constructed using SAMs to pass functions to other functions. Before Java 8 you had to write a lot of code to create an instance of a SAM and pass it to the function. Now you can just use a lambda of the correct type.



Last Updated ( Tuesday, 14 November 2017 )
 
 

   
Banner
Copyright © 2017 i-programmer.info. All Rights Reserved.
Joomla! is Free Software released under the GNU/GPL License.