11.5. How to Create Lambda Expressions¶
The easiest way to create a lambda expression is by pretending to assign your intended method override to a variable of the interface type. Here's an example:
Assign your intended method override to a variable of the interface type:
Consumer<String> shout = @Override public void accept(String t) { return System.out.println(t.toUpperCase()); };
Remove the annotation (
@Override), the visibility modifier (public), the return type (void) and the method name (accept):Consumer<String> shout = (String t) { System.out.println(t.toUpperCase()); };
Add an arrow (
->) between the parameter list and the opening curly brace:Consumer<String> shout = (String t) -> { System.out.println(t.toUpperCase()); };
Notice that the parameter above has type String. When we write the
parameter types explicitly, they must match the parameter types of the
functional interface's abstract method after substituting its type
arguments. For Consumer<String>, the parameter of accept has type
String. Writing Object t instead would not work, even though
Object is a superclass of String.
Let's apply this to another interface that we will use with JavaFX.
EventHandler<T> declares void handle(T event). For
EventHandler<ActionEvent>, that parameter has type ActionEvent:
EventHandler<ActionEvent> h1 = (ActionEvent event) -> { }; // valid
EventHandler<ActionEvent> h2 = event -> { }; // valid: inferred
The following alternatives do not compile in a context where T has
not been declared as a type:
EventHandler<ActionEvent> h3 = (Event event) -> { }; // wrong parameter type
EventHandler<ActionEvent> h4 = (T event) -> { }; // T is not declared
The type arguments of an interface do not tell us how many parameters
its abstract method has. For example, Function<String, Integer> has
one parameter of type String and a result type of Integer.
A lambda expression for it might be text -> text.length(). The
int result of length is boxed to Integer; it is not a
second parameter. Inspect the abstract method's declaration when you
are unsure which parameters to write.
Shorter Lambda Syntax (Optional)
The three-step process above leads to a valid lambda expression; however, there's still room for improvement.
If the method body only contains a single statement, then we can omit the curly braces all together and write the lambda expression on a single line:
Consumer<String> shout = (String t) -> System.out.println(t.toUpperCase());
If the only statement is a return statement, then the keyword return is omitted when writing a lambda expression without curly braces.
Specifying the parameter types is optional.
Consumer<String> shout = (t) -> System.out.println(t.toUpperCase());
If we don't include the parameter types in our lambda expression, then Java will try to determine what they are based on context. For example, if we're assigning the created object to a
Consumer<String>variable, then Java knows that the parameter list foracceptis(String t)and will inferStringas the parameter type. If we write the type ourselves, the exact-type rule above still applies.If there is exactly one method parameter, then the parentheses for the parameter list are optional.
Consumer<String> shout = t -> System.out.println(t.toUpperCase());
If the method doesn't have any parameters, then parentheses are still required, and
() ->is used.
Test Yourself
Use a lambda expression to create a consumer that prints the length of a string.
Use a lambda expression to create a consumer that prints the number of exclamation marks in a string.
Use a lambda expression to create a discount strategy that reduces the original price by 25% and subtracts an additional five dollars (if the item is not below five dollars already).
Test Yourself Solutions (open after completing the questions above)
One possible solution:
Consumer<String> printLength = (String s) -> { System.out.println(s.length()); };
We won't give exact solutions to the other two questions
above. However, you can try it and test the result. Go ahead and
write your lambda expressions in the main method of the
Driver class you compiled in the previous section. Then,
compile and run the code to make sure it works as expected. If you
get stuck, post your question and the lambda expression you used to
Piazza for assistance.