Java. Throwing exceptions in lambda expressions. Examples

Throwing exceptions in lambda expressions. Examples


Contents


Search other websites:




1. Features of throwing exceptions in lambda expressions

There are times when an exception can occur in lambda expressions. In this case, the lambda expression should throw an exception. Throwing an exception by a lambda expression is implemented in the standard way using the throw statement. The fragment to be checked in the lambda expression is placed in a try-catch block.

As with a method, you can throw two kinds of exceptions in a lambda expression:

  • predefined Java types (ArithmeticException, ArrayIndexOutOfBoundsException, etc.);
  • self-developed exceptions classes.

 

2. Examples generating standard exception in lambda expression
2.1. Division of two numbers. Throwing a division by zero exception

The example provides a lambda expression that returns the result of dividing two numbers. The lambda expression code checks the divisor value. If this value is 0, then a standard ArithmeticException is thrown with an appropriate message.

// Generating exceptions in lambda expressions
// Declare a functional interface
interface IDivNumbers {
  // Declare a method that divides two numbers
  double Division(double a, double b);
}

// A class that contains methods that implement
// lambda expressions and test the program.
public class Lambda {

  public static void main(String[] args) {

    // 1. Declare a reference to IDivNumbers
    IDivNumbers ref;

    // 2. Implement a lambda expression that divides two numbers
    //    and throws an exception if necessary
    ref = (a, b) -> {
      try {
        // Process division by 0 check
        if (b==0)
          throw new ArithmeticException("Exception: divide by zero.");
        return a/b; // if b! = 0, then return the result of division
      }
      catch (ArithmeticException e) {
        System.out.println(e.getMessage()); // Print the error message
        return 0.0;
      }
    };

    // 3. Test lambda expression for exception
    double res = ref.Division(5, 0); // Exception: divide by zero.

    // 4. Print the result
    System.out.println("res = " + res); // res = 0.0
  }
}

The result of the program

Exception: divide by zero.
res = 0.0

 

2.2. Element-wise summation of arrays. Template functional interface. Throwing an exception in a lambda expression. Passing a lambda expression to a method

Task. Using the lambda expression mechanism, implement elementwise summation of arrays of the generic type T. The lambda expression must handle the following exceptions thrown when arrays do not meet the specified requirements.

Basic requirements for arrays:

  • arrays must support numeric types;
  • arrays must be of nonzero length. If one of the arrays has zero length, then throw an EmptyArrayException exception. To implement the EmptyArrayException exception, develop a class of the same name;
  • arrays must be the same length. If the arrays have different lengths, then throw a standard ArrayIndexOutOfBoundsException. The lambda expression must be passed to the method as a parameter. To do this, you need to declare an additional class with a method that takes a lambda expression as a parameter.

In the main() function, demonstrate the use of lambda expressions to handle exceptions.

Solution. According to the condition of the problem, the following classes and interface must be entered in the program:

  • generalized (template) functional interface ISumArrays<T>, which operates on the numeric type T. The interface type is limited to Number (all numeric types). In the interface, you need to define the SumArrays() method, which receives two arrays as a parameter and returns the resulting array;
  • the EmptyArrayException class, which defines the exception that is thrown when one of the arrays is of length zero;
  • an ArrayMethod class that contains a single AddMethod() method. This method receives three parameters: two arrays-addends and a lambda-expression as a reference to ISumArrays<T>;
  • the Lambda class in which the main() function is declared. The main() function creates test arrays for various types and a lambda expression. All this data is passed to the AddMethod() method of the ArrayMethod instance.

The text of the solution to the problem is given below.

// Throwing Exceptions in Lambda Expressions
// Declare a generic functional interface that operates on type T.
// Type T is limited to numeric types (Number).
interface ISumArrays<T extends Number> {
  // Method that takes two arrays and returns an array
  T[] SumArrays(T[] array1, T[] array2);
}

// The class that defines the exception that is thrown
// when one of the arrays is of length zero.
// The class must inherit from the Exception class
class EmptyArrayException extends Exception {

  // Class constructor
  EmptyArrayException(String message) {
    super(message); // call superclass constructor
  }
}

// A generic class that contains the method to which the lambda expression is passed.
// The method calls another SumArrays() method of the ISumArrays interface to sum the elements.
class ArrayMethod<T extends Number> {
  // Method that takes a lambda expression as a parameter
  public T[] AddMethod(T[] array1, T[] array2, ISumArrays<T> ref) {
    T[] array3 = null;
    array3 = ref.SumArrays(array1, array2); // return the sum of arrays
    return array3;
  }
}

// A class that contains methods that implement
// the lambda expression and test the operation of the program
public class Lambda {

  public static void main(String[] args) {

    // 1. Implementation for arrays of type Double
    // 1.1. Declare a reference to ISumArrays<T>
    ISumArrays<Double> ref;

    // 1.2. Generate a lambda expression with binding to the Double type
    ref = (array1, array2) -> {
      try {
        // Checking for zero length of arrays
        if (array1.length==0)
          throw new EmptyArrayException("array1 is empty.");
        if (array2.length==0)
          throw new EmptyArrayException("array2 is empty.");

        // Checking for equality of elements in arrays
        if (array1.length!=array2.length)
          throw new ArrayIndexOutOfBoundsException("Arrays are not equal");
      }
      catch (EmptyArrayException e) {
        System.out.println(e.getMessage());
        return null;
      }
      catch (ArrayIndexOutOfBoundsException e) {
        System.out.println(e.getMessage());
        return null;
      }

      // Arrays summing code
      Double[] array3 = new Double[array1.length];
      for (int i=0; i<array1.length; i++)
        array3[i] = array1[i] + array2[i];
      return array3;
    };

    // 1.3. Declare two arrays of different length
    Double[] AD1 = { 2.0, 1.5, 3.8 };
    Double[] AD2 = { 1.1, 4.0 };

    // 1.4. Invoke method AddMethod() of class ArrayMethod<T>
    Double[] AD3;
    ArrayMethod<Double> obj = new ArrayMethod<Double>();
    AD3 = obj.AddMethod(AD1, AD2, ref);

    // 1.5. Print the AD3 array
    if (AD3 != null) {
      System.out.println("Array AD3:");
      for (int i=0; i<AD3.length; i++)
        System.out.print(" " + AD3[i]);
      System.out.println();
    }

    // 2. Implementation for identical arrays
    // 2.1. Declare identical arrays
    Double[] AD4 = { 1.5, 2.5, 3.3 };
    Double[] AD5 = { 2.0, 1.8, 1.9 };

    // 2.2. Call the method for summing arrays
    AD3 = obj.AddMethod(AD4, AD5, ref);

    // 2.3. Print the AD3 array
    if (AD3 != null) {
      System.out.println("Array AD3:");
      for (int i=0; i<AD3.length; i++)
        System.out.print(" " + AD3[i]);
      System.out.println();
    }
  }
}

The result of the program

Arrays are not equal
Array AD3:
3.5 4.3 5.199999999999999

 

3. An example of throwing an exception that is handled by a specially designed class

Task. Develop a NegativeRootException class that handles the exception thrown when an attempt is made to take the square root of a negative number. Implement a lambda expression that calculates the area of a triangle from the lengths of its sides. The calculation is based on Heron’s formula. If a root of a negative number occurs in Heron’s formula (the triangle does not exist), then throw a NegativeRootException. The exception must be thrown in a lambda expression.

Solution. The text for solving the problem is as follows.

// Generating exceptions in lambda expressions
// Declare a functional interface
interface INegativeRoot {
  // Declare a method that determines the area of a triangle by its sides
  double AreaTriangle(double a, double b, double c);
}

// Create an exception class that handles the square root of a negative number
// Such an exception is checked.
class NegativeRootException extends Exception {
  // Class constructor
  NegativeRootException(String message) {
    super(message); // Call the constructor of superclass Exception
  }
}

// A class that contains methods that implement the lambda
// expression and test the operation of the program.
public class Lambda {

  @SuppressWarnings("finally")
  public static void main(String[] args) {

    // 1. Declare a reference to INegativeRoot
    INegativeRoot ref = null;

    // 2. Implement a lambda expression that calculates
    //   the area of a triangle using Heron's formula
    ref = (a, b, c) -> {
      double p = (a+b+c)/2; // semiperimeter
      double t = p*(p-a)*(p-b)*(p-c); // root expression

      try {
        // check for negative root with throwing an exception
        if (t<0) {
          t=0;
          throw new NegativeRootException("Exception: negative root.");
        }
        return Math.sqrt(t);
      }
      catch (NegativeRootException e) {
        t = 0;
        System.out.println(e.getMessage());
      }
      finally {
        // Block that is always executed
        return t;
      }
    };

    // 3. Test lambda expression for exception
    double res = ref.AreaTriangle(1, 1, 5); // Exception: negative root.

    // 4. Print the result
    System.out.println("res = " + res); // res = 0.0
  }
}

After execution, the program will give the following result

Exception: negative root.
res = 0.0

 


Related topics