How To Throw Exception In Java 8 Lambda Function – Detailed Guide

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 Uppercaseusing 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 method convert() 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).

Related Topics

Leave a Comment