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:

  1. Assign your intended method override to a variable of the interface type:

    Listing 11.8 This won’t compile, but it’s a good way to get started
    Consumer<String> shout = @Override public void accept(String t) {
        return System.out.println(t.toUpperCase());
    };
    
  2. Remove the annotation (@Override), the visibility modifier (public), the return type (void) and the method name (accept):

    Listing 11.9 this still won’t compile, but it’s only two characters away from working
    Consumer<String> shout = (String t) {
        System.out.println(t.toUpperCase());
    };
    
  3. Add an arrow (->) between the parameter list and the opening curly brace:

    Listing 11.10 this WILL compile; we provided a valid lambda expression!
    Consumer<String> shout = (String t) -> {
        System.out.println(t.toUpperCase());
    };
    
Shorter Lambda Syntax (Optional)

The three-step process above leads to a valid lambda expression; however, there’s still room for improvement.

  1. 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.

  2. 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 for accept is (String t) and will automatically convert (t) to (String t).

  3. 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

  1. Use a lambda expression to create a consumer that prints the length of a string.

  2. Use a lambda expression to create a consumer that prints the number of exclamation marks in a string.

  3. 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)
  1. 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! To 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.