The Java 8 Lambda function helps invoke single-method class instances more compactly.
You can use Lambda functions to invoke a functional interface and throw an exception inside the functional interface implementation
In this tutorial, You will learn different ways to throw an exception from a Java 8 lambda function.
Throw Exception From Predefined Functional Interface
The Java 8 FunctionalInterface contains exactly one abstract method and Lambda functions can be used to create instances of functional interfaces.
Java 8 provides many functional interfaces like Function, Predicate< T >, Supplier< T > and more with their purpose to use.
Code
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
//main
List<String> names = new ArrayList<>(Arrays.asList("?Max", "%%Kani", ">>Browny", "Jessi"));
System.out.println(names); //[?Max, %%Kani, >>Browny, Jessi]
List updatedNames = names.stream().map(value -> value.toUpperCase()).collect(Collectors.toList());
System.out.println(updatedNames); //[?MAX, %%KANI, >>BROWNY, JESSI]
In the above example, the names
field values contain special characters and are converted to Uppercase
using the map function.
You can restrict the map function to throw an exception inside the lambda function when any non-alphabets are encountered.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
//main
List<String> names = new ArrayList<>(Arrays.asList("?Max", "%%Kani", ">>Browny", "Jessi"));
System.out.println(names); //[?Max, %%Kani, >>Browny, Jessi]
Function<String, String> function = str -> {
if(!str.matches("[a-zA-Z]+")){
throw new InputMismatchException("Only alphabets allowed");
}
return str.toUpperCase();
};
List updatedNames = names.stream().map(value-> function.apply(value)).collect(Collectors.toList());
System.out.println(updatedNames);
Output
Exception in thread "main" java.util.InputMismatchException: Only alphabets allowed
Inside the lambda function, a condition is added to check for non-alphabets in the string. If the string contains non-alphabets, InputMismatchException is thrown with the custom message Only alphabets allowed
.
Throw RunException Inside Lambda function
Custom Functional Interfaces can be used to handle specific business requirements.
To create a custom functional interface and throw an exception inside the lambda function while invoking a custom interface,
- Create an
interface
with one abstract methodconvert()
and annotate with@FunctionalInterface
. - Specify input date types(
<A,B>
), return type(<R>
) and exception(<E>
) - invoke the functional interface(
PercentageFunction
) and use lambda function(->
) to pass the values to the functional interface. - Handle exceptions inside the lambda function to process the exceptions thrown at runtime.
Code
//PercentageFunction.java
@FunctionalInterface
public interface PercentageFunction<A, B, R, E extends Exception> {
R convert(A a, B b);
//A, B - Date type of input parameters
//R - Return type
}
import com.techmam.PercentageFunction;
//main
PercentageFunction<Integer, Integer, Integer, ArithmeticException> percentageFunction = (a, b) -> {
try{
return (a / b);
}catch(ArithmeticException e){
System.out.println("Exception occurred {}"+ e.getMessage());
return 0;
}
};
List<Integer> numbers = Arrays.asList(5,4,3,2,1,0);
List<Integer> percentageValue = numbers.stream().map(value->percentageFunction.convert(value*2, value)).collect(Collectors.toList());
System.out.println(percentageValue);
Output
Exception occurred {}/ by zero
[2, 2, 2, 2, 2, 0]
In the above example, the stream of values is given to a map(value->fn(value*2, value))
function. A division operation is performed on the input parameters inside the lambda function. ArithmeticException is thrown inside the lambda on error mathematical errors. These errors are handled, and a value of 0
is returned on the exception scenario.
Throw Custom Exception Inside Lambda Function
You can throw custom exceptions inside the lambda function as the predefined exceptions are thrown.
Code
import com.techmam.AgeFunction;
import java.time.LocalDate;
//AgeException.java
public class AgeException extends Exception {
AgeException(String message){
super(message);
}
}
//AgeFunction.java
@FunctionalInterface
public interface AgeFunction<T,R> {
R calculate(T t) throws AgeException;
//T - Date type of input parameter
//R - Return type
}
//main
AgeFunction<LocalDate, Integer> ageFunction = (date) -> {
int age = LocalDate.now().getYear() - date.getYear(); //current year = 2023
if (age < 18) {
throw new AgeException("Age not accepted");
}
return age;
};
try {
int age = ageFunction.calculate(LocalDate.of(2020, 1, 1));
System.out.println(age);
} catch (AgeException e) {
System.out.println("Exception occurred : " + e.getMessage());
}
Output
Exception occurred : Age not accepted
The above example calculates the Age value inside the lambda function by subtracting the year passed in the argument and the current year. When the age is less than <18
, then a custom exception(AgeException
) is thrown with a message(Age not accepted
).