Sunday, March 6, 2016

Lambdas in Java

Of the features introduced with Java 8, lambdas is without a doubt the most popular and the first that comes to mind. Let's see how it works in practice.

Syntax

We are going to write a lambda function (also known simply as "lambda") that concatenates two strings.

Code Description
new Concatenator() {
  String concatenate(String a, String b) { 
    return a + b;
  }
}
The equivalent interface and method.
You can actually use this in place of the lambda, the output from the compiler of all these forms is the same.
IntelliJ will tell you you can simplify this expression using a lambda function.
(String a, String b) -> { return a + b; }
The long and most descriptive lambda version.
Don't forget the semi-colon.
(a, b) -> { return a + b; }
The parameter types can be inferred by the compiler.
(a, b) -> a + b
Usually a lambda is used to return a value, so if you can write your method in only one return statement, you can simplify it like this.
You will need curly braces and "return" if more statements are needed.
(a) -> a.toLowercase()
You can simplify further this way if only one parameter is required.
a -> a.toLowercase()
And even further
String::toLowercase
It doesn't get shorter than this. Isn't that prettier and more concise than writing the equivalent anonymous class?

Writing a method that takes a lambda as parameter

Now, let's say you want that users of your method to provide a lambda for you to profit from.
As explained above, lambdas in Java is only a syntactic sugar. You only need to think about some class or interface having a method you can use.

First define that interface:
Interface for lambdas
@FunctionalInterface
public interface Concatenator {
     String concatenate (String a, String b);

@FunctionalInterface is optional, it is only an indicator.

And here is the method that uses a lambda as parameter:
Method that uses a lambda
private void methodUsingLambda(Concatenator concatenator) {
    System.out.println(concatenator.concatenate("James ""Bond"));

That's it!

Functional interfaces

It would be silly to write our own interfaces all the time. There are a bunch of them in the package java.util.function that we can use, such as:

Interface Parameter(s) Return value
Supplier<R>
BooleanSupplier
IntSupplier
-
R
boolean
int
UnaryOperator<T>
T
T
Predicate<P>
BiPredicate<P,T>
P
P, T
boolean
Consumer<P>
BiConsumer<P,T>
P
P, T
-
Function<P>
BiFunction<P,R>
P
P, T
R
Runnable
-
-

Note that Runnable is in the java.lang package. It is also annotated as a functional interface. I guess they already had it there, so they didn't make a new version in java.util.function.

No comments:

Post a Comment