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.

  • 2
    Use a method reference– MichaelFeb 14 at 21:07
  • Why not put the entire method call inside the try block?– shmoselFeb 14 at 21:07
  • 1
    @Michael How is that at all relevant?– shmoselFeb 14 at 21:08
  • @shmosel yes I can do that but it woudn't be specific to the lambda if that makes sense.– GuruFeb 14 at 21:11
  • 2
    You can declare static method divide(Integer v, Integer k) { try{ System.out.println(v/k); } catch(ArithmeticException e){ //handle exception } }, and now you can just use process(someNumbers, key, ExceptionHandlingLambda::divide) I think this is what @Michael is meaning by suggesting to use method reference– boobalanFeb 14 at 21:21

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 returnhttp:// 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");}};}
  • That is not what Michael and boobalan were suggesting.– VGRFeb 14 at 22:15
  • @VGR I have added the method reference as well. Looks cleaner now.– GuruFeb 15 at 14:08
  • Still incorrect. Remove all occurrences of -> from your code. Your private method’s signature should be void methodName(Integer v, Integer k), and its body should only consist of a try/catch whose body is System.out.println(v / k);. No lambdas should be present and there should be no usage of BiConsumer in the private method. The method will implicitly conform to the BiConsumer functional interface and thus a reference to it will qualify as a BiConsumer instance.– VGRFeb 15 at 18:07

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.

  • 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); } }– GuruFeb 14 at 21:40
  • It is not generic If you parse ArithmeticException in an argument. then it will only handle ArithmeticException else will throw a ClassCastException. In second catch block, you can write additional logic to handle exceptions other than ArithmeticException– Jayant NarwaniFeb 14 at 21:50

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.