Java 8 Lambda Expressions: Difference between revisions

From NovaOrdis Knowledge Base
Jump to navigation Jump to search
No edit summary
Line 22: Line 22:
The term ''lambda'' comes from a system developed in academia called [https://en.wikipedia.org/wiki/Lambda_calculus lambda calculus], which is used to describe computations.
The term ''lambda'' comes from a system developed in academia called [https://en.wikipedia.org/wiki/Lambda_calculus lambda calculus], which is used to describe computations.


==Syntax==
=Syntax=


A lambda expression declaration consists in a [[#Formal_Parameters|comma-separated list of formal parameters]], enclosed in parentheses, followed by the "arrow" token, followed by a [[#The_Body|body]].
A lambda expression declaration consists in a [[#Formal_Parameters|comma-separated list of formal parameters]], enclosed in parentheses, followed by the "arrow" token, followed by a [[#The_Body|body]].
Line 28: Line 28:
  (''comma-separated-parameter-list'') -> ''body''
  (''comma-separated-parameter-list'') -> ''body''


===Formal Parameters===
==Formal Parameters==


The most generic format of the ''parameter-list'' is:
The most generic format of the ''parameter-list'' is:
Line 50: Line 50:
"->" is referred to as "arrow".
"->" is referred to as "arrow".


===The Body===
==The Body==


The ''body'' can be a single [[Java_Language#Expressions|expression]], and it this case the lambda is known as an "[[#Expression-Style_Lambda|expression-style lambda]]", or a list of [[Java_Language#Statements|statements]] included enclosed in curly braces - a block - and in this case the lambda is known as "[[#Block-Style_Lambda|block-style lambda]]".
The ''body'' can be a single [[Java_Language#Expressions|expression]], and it this case the lambda is known as an "[[#Expression-Style_Lambda|expression-style lambda]]", or a list of [[Java_Language#Statements|statements]] included enclosed in curly braces - a block - and in this case the lambda is known as "[[#Block-Style_Lambda|block-style lambda]]".


====Block-Style Lambda====
===Block-Style Lambda===


  (''parameter-list'') -> { ''statement1''; ''statement2''; ... }
  (''parameter-list'') -> { ''statement1''; ''statement2''; ... }
Line 82: Line 82:
</syntaxhighlight>
</syntaxhighlight>


====Expression-Style Lambda====
===Expression-Style Lambda===


  (''parameter-list'') -> ''expression''
  (''parameter-list'') -> ''expression''

Revision as of 19:35, 23 March 2018

External

Internal

Overview

Java 8 introduces functional programming features, in the form of lambda expressions. Lambda expressions allow behavior parameterization - functions can be now assigned to variables, as values, and passed around, which essentially means passing code around. Functions come in form of lambda expressions (anonymous functions) or method references.

Lambda Expression

A lambda expression is a representation of an anonymous function: it does not have a name, but it has a list of parameters, a body, a return type, and possibly a list of exceptions that can be thrown.

Lambda expressions can be stored as values, in variables, and passed as arguments to methods and constructors. In all these cases, the type of the lambda value is a functional interface.

Semantically, lambda expressions do not allow programmers to do anything that couldn't have been done before their introduction in Java 8, via anonymous classes. However, the lambda syntax is more concise, lambda expressions are a convenient way of increasing the code clarity by in-lining logic. If the lambda's body exceeds a few lines in length, so that its behavior isn't instantly clear, the logic should be encapsulated in a method and a method reference should be used instead of the lambda expression.

The term lambda comes from a system developed in academia called lambda calculus, which is used to describe computations.

Syntax

A lambda expression declaration consists in a comma-separated list of formal parameters, enclosed in parentheses, followed by the "arrow" token, followed by a body.

(comma-separated-parameter-list) -> body

Formal Parameters

The most generic format of the parameter-list is:

([Type1] var1, [Type2] var2, ...)

The type of parameters may be omitted, thanks to the type inference mechanism.

If and only if there is a single parameter, the enclosing parentheses may be omitted, along with the type specification. Note that omitting only the parentheses, but not the type specification is considered a syntax error, both must be omitted at the same time. Example:

a -> ...

The parameter list could be empty, but in this case the parentheses are required:

 () -> ...

"->" is referred to as "arrow".

The Body

The body can be a single expression, and it this case the lambda is known as an "expression-style lambda", or a list of statements included enclosed in curly braces - a block - and in this case the lambda is known as "block-style lambda".

Block-Style Lambda

(parameter-list) -> { statement1; statement2; ... }

The absence of a return as the last statement in the block implies that the lambda returns void:

(Apple a) -> { 
    System.out.println("the apple is " + a.getColor());
    System.out.println("the apple weighs " + a.getWeight() + " grams");
};

This lambda, that has no parameters and returns void, is valid:

() -> {}

If the lambda execution returns a value, the last statement in the block must be return:

(Apple a) -> { 
    boolean heavy = a.getWeight() > 100; 
    return a.getColor() + "(" + (heavy ? "heavy":"light") + ")"; 
};

Expression-Style Lambda

(parameter-list) -> expression

If the lambda is supposed to return a value, then the value the expression evaluates to is returned as value of lambda execution.

(Apple a) -> a.getColor() + " (" + a.getWeight() + " grams)";

If the lambda is supposed to return void, the value the expression evaluates to is discarded.

Functional Interface

A lambda value type is given by a functional interface: lambda values can be used and passed around everywhere a functional interface is expected.

A functional interface is a Java interface that specifies exactly one abstract method. Note that an interface that has exactly one abstract method and several default methods is still a valid functional interface.

The functional interface's abstract method signature - the parameter list, the return type and possibly the exceptions thrown - must match the lambda expression signature.

@FunctionalInterface

Library interfaces annotated with @FunctionalInterface:

Predicate

A predicate is a function that evaluates an argument and returns a boolean.

https://github.com/NovaOrdis/playground/tree/master/java/java8/lambda-expressions/02-predicate

Method Reference

The semantics behind the method reference syntax is use this method as a value.

The <Class-Name>::<method-name> syntax creates a method reference, which then can be passed around as a value.

Relationship between Lambda Expressions and Method References

TODO