0

I have some code that throws a checked exception. I want to call that code within a lambda in order to create a map from another map:

Map<String, Coordinate> map = getMap(); Map<String, Integer> result = map.entrySet().stream().collect( toMap(x -> x.getKey(), x -> doSomething(x.getValue))); 

where doSometing is the code that throws the exception:

int doSomething(Coordinate c) throws MyException { ... } 

Now compiler surely complains about the exception not being handled. So I surround it with a try-catch, which looks pretty ugly:

Map<String, Integer> result = map.entrySet().stream().collect( toMap(x -> x.getKey(), x -> { try { return doSomething(x.getValue()); } catch (MyException e) { e.printStackTrace(); // return some error-code here??? } })); 

which also does not compile as we need to return something in the catch-case. However there´s not much sense in returning anything here in this exceptional case, which is why I actually do not want to handle the exception at that level. Can´t I just handle the exception in my calling code, where I create the lambda? So to say just one level above?

try { Map<String, Integer> result = ... } catch (MyException e) { ... } 

But that does not compile because the exception thrown from the lambda is not handled.

6
  • 1
    The question here would be, why would you want to use checked exception. Also, I believe that the standard way of handling checked exceptions in labdas (if you cannot just make it runtime) is to catch it inside lamda and rethrow an unchecked exception - you can use checked one as cause. Commented Feb 4, 2020 at 14:08
  • @Worthless Unfortunately doSomething is a 3rd-party-API that just throws. Commented Feb 4, 2020 at 14:09
  • Then yea, rethrowing is probably the easiest way to handle it. Commented Feb 4, 2020 at 14:10
  • @Worthless But how to do that in a nice way? Isn´t it possible to just let the exception bubble through the layers until it finally is handled? Commented Feb 4, 2020 at 14:12
  • Checked exceptions can't bubble through until it is handled. Each intervening method has to declare it. Commented Feb 4, 2020 at 14:16

2 Answers 2

1

From Baeldung's blog: you could define consumer which can throw Exception:

@FunctionalInterface public interface ThrowingConsumer<T, E extends Exception> { void accept(T t) throws E; } 

and a static wrapper to map checked exception to RuntimeException:

static <T> Consumer<T> throwingConsumerWrapper( ThrowingConsumer<T, Exception> throwingConsumer) { return i -> { try { throwingConsumer.accept(i); } catch (Exception ex) { throw new RuntimeException(ex); } }; } 

Then you can call it:

Map<String, Integer> result = map.entrySet().stream() .collect( throwingConsumerWrapper(toMap(x -> x.getKey(), x -> doSomething(x.getValue))) ); 
Sign up to request clarification or add additional context in comments.

1 Comment

I already found this, but I coudn´t get the toMap working, because I just wrapped the x -> doSomething-part. Thatnks for the answer.
0

Fist of all it's worth to filter your values. In case if you have values which can raise an exception.

Then you can use one of the popular wrappers (i.e. jooq.lambda) or write your own

 map.entrySet().stream() .filter(x -> makeSureNoExtection(x)) .collect(toMap(x -> x.getKey(), unchecked(x -> doSomething(x.getValue)))); 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.