CS F213 Objected Oriented Programming Labsheet 12

Spring 2024

Java Lambda Expressions

The lambda expression was introduced first time in Java 8. Its main objective to increase the expressive power of the language.

Lambda expression is, essentially, an anonymous or unnamed method. The lambda expression does not execute on its own. Instead, it is used to implement a method defined by a functional interface.

Syntax

(parameter list) -> lambda body

The new operator (->) used is known as an arrow operator or a lambda operator. The syntax might not be clear at the moment. Let's explore some examples,

Suppose, we have a method like this:

double getPiValue() {
    return 3.1415;
}

We can write this method using lambda expression as:

() -> 3.1415

Here, the method does not have any parameters. Hence, the left side of the operator includes an empty parameter. The right side is the lambda body that specifies the action of the lambda expression. In this case, it returns the value 3.1415.

Types of Lambda Body

1. A body with a single expression

() -> System.out.println("Lambdas are great");

2. A body that consists of a block of code.

This type of the lambda body is known as a block body. The block body allows the lambda body to include multiple statements. These statements are enclosed inside the braces and you have to add a semi-colon after the braces.

Note: For the block body, you can have a return statement if the body returns a value. However, the expression body does not require a return statement.

Lambda Expressions with parameters

Till now we have created lambda expressions without any parameters. However, similar to methods, lambda expressions can also have parameters. For example,

Here, the variable n inside the parenthesis is a parameter passed to the lambda expression. The lambda body takes the parameter and checks if it is even or odd.

Example

Let's write A block lambda that computes the factorial of an int value.

As mentioned earlier, a lambda expression is not executed on its own. Rather, it forms the implementation of the abstract method defined by the functional interface.

Output

Generic Functional Interfaces

Till now we have used the functional interface that accepts only one type of value. However, we can make the functional interface generic, so that any data type is accepted.

Example

Let's write a program on Generic Functional Interface and Lambda Expressions which uses one single interface and calculates factorial of a number as well as reverses a string.

Output

The SomeFunc interface is used to provide a reference to two different types of lambdas. The first uses type String. The second uses type Integer. Thus, the same functional interface can be used to refer to the reverse lambda and the factorial lambda. Only the type argument passed to SomeFunc differs.

Lambda Expressions to run thread

You can use lambda expression to run thread. In the following example, we are implementing run method by using lambda expression.

Passing Lambda Expressions as Arguments

To pass a lambda expression as an argument, the type of the parameter receiving the lambda expression argument must be of a functional interface type compatible with the lambda. Although using a lambda expression as an argument is straightforward, it is still helpful to see it in action.

Example

Convert an ArrayList to uppercase using replaceAll method of ArrayList and passing lambda expression to it

Output

Lambda Expressions and Exceptions

A lambda expression can throw an exception. However, it if throws a checked exception, then that exception must be compatible with the exception(s) listed in the throws clause of the abstract method in the functional interface.

Example

It computes the average of an array of double values. If a zero-length array is passed, however, it throws the custom exception EmptyArrayException.

Remember, the inclusion of the throws clause in func( ) is necessary. Without it, the program will not compile because the lambda expression will no longer be compatible with func( ).

Exercises

Exercise 1

Write a Java program that demonstrates the use of block lambda expressions to filter a list of strings based on their length. The program should utilize a functional interface

which filters strings from a given list based on a minimum length, i.e. only strings with length >= minimum length are filtered and printed.

Sample Input

Sample Output

Hint : create a new list inside the block lambda expression, check for length and add filtered strings to it, then return the list and store it outside during the method call. Then print it.

Exercise 2

Enhance the provided Java program to calculate the factorial of an integer and reverse a string concurrently using threads, while implementing their run methods using lambda expressions only. The program should utilize a single generic interface SomeFunc to represent both operations. Create two different threads for both operations and then start them.

Exercise 3

Write a Java program that allows dividing two numbers of integer, double, or float data types. The program should take the data type from the user, apply conditional statements to implement a generic interface using lambda expressions, and handle the scenario where the second number is zero by throwing an Arithmetic exception.

Sample Inputs

Sample Outputs

Last updated