Guru
Guru

Reputation: 1883

Java Streams Exception handling. Best way for cleaner code

I have the below code

import java.util.function.BiConsumer;

public class ExceptionHandlingLambda {

    public static void main(String[] args) {
        int [] someNumbers = { 1, 2, 3, 4 };
        int key = 2;

        process(someNumbers, key, (v,k) -> {
            try{
                System.out.println(v/k);
            }
            catch(ArithmeticException e){
                //handle exception
            }
        });

    }

    private static void process(int[] someNumbers, int key, BiConsumer<Integer, Integer> consumer) {
        for (int i : someNumbers) { 
          //can put a try catch here but this is generic and we don't know what exception we are catching.          
            consumer.accept(i, key);
        }

    }
}

I am trying to handle some exception in a lambda. From above I have handled an exception within a lambda. I think it makes my lambda look kind of messy.

I could also handle the exception in the process method but it would be generic and we wouldn't know what exception we are handling for.

Any other better way to handle this in lambda to have cleaner code? Any suggestions would be much appreciated.

Upvotes: 1

Views: 201

Answers (2)

Guru
Guru

Reputation: 1883

After the suggestion from some great and kind minds I have an answer. Hope this helps someone.

process(someNumbers, key, wrapperLambda((v, k) -> System.out.println(v / k))); 

//with method reference 
process(someNumbers, key, ExceptionHandlingLambda::wrapperLambda);

A wrapper function for lambda which accepts a lambda and return a lambda with a try catch which makes it much cleaner.

private static BiConsumer<Integer, Integer> wrapperLambda(BiConsumer<Integer, Integer> consumer) {
        //creating a new lambda and return.
        // return (v,k) -> System.out.println(v+k); this would replace the lambda with addition lambda (v+k)

        return (v, k) ->  {
            try {
                consumer.accept(v, k); //execute whatever is passed in. 
            }
            catch (ArithmeticException e) {
                System.out.println("Exception caught in wrapper lambda");
            }

        };
}

Upvotes: 2

Jayant Narwani
Jayant Narwani

Reputation: 101

Apply try catch in your process method and pass an additional argument to the method i.e. the exception class for which you want to handle the exception.

Process method would look like

private static void process(int[] someNumbers, int key, BiConsumer<Integer, Integer> consumer, Class<E> clazz) {
    for (int i : someNumbers) { 
       try{
        consumer.accept(i, key);
     } catch(Exception ex) {
         try {
            E exCast = clazz.cast(ex);
            System.err.println(
              "Exception occured : " + exCast.getMessage());
        } catch (ClassCastException ccEx) {
            throw ex;
        }
      }
    }

}

This way your lambda would not look messy and you can decide which exception to be handled at the time of calling.

Upvotes: -1

Related Questions