Home > Mobile >  Why java streams are not able to handle exception even after surrounding with a try-catch block?
Why java streams are not able to handle exception even after surrounding with a try-catch block?

Time:12-21

I have the following piece of code with java streams

Problematic code

You can see that I am having an error on the 4th line. Basically the error says Unhandled Exception: AddressException. But you can see that I am catching it within catch block. But still that is not working. Eventhough, if I use a try catch block within the map method it works as shown below

  public List<InternetAddress> getListOfInternetEmailAddresses(List<String> toEmails){
       List<InternetAddress> internetAddresses = new ArrayList<>();
            internetAddresses = toEmails.stream().map(a->{
                InternetAddress ia = null;
                try{
                   ia = new InternetAddress(a);
                } catch (AddressException e) {
                    
                }
                return ia;
            }).collect(Collectors.toList());
        return internetAddresses;
    }

Does anyone know why this behaviour and if knows please give some insights to that. One more quetion, does the anonymous inner class will also behave the same ?

CodePudding user response:

Error is shown because you provided method with different signature (additional thows clause). You have to provide implementation that is compatible with java.util.function.Function#apply signature

R apply(T var1);

There is several ways to deal with your problem:

  • anonymous function with try-catch
    public List<InternetAddress> getListOfInternetEmailAddresses(List<String> toEmails) {
        return toEmails.stream().map(new Function<String, InternetAddress>() {
            @Override
            public InternetAddress apply(String email) {
                try {
                    return new InternetAddress(email);
                } catch (AddressException e) {
                    e.printStackTrace();
                }
                return null;
            }
        }).collect(Collectors.toList());
    }
  • try-catch in lambda
    public List<InternetAddress> getListOfInternetEmailAddresses(List<String> toEmails) {
        return toEmails.stream().map(email -> {
            try {
                return new InternetAddress(email);
            } catch (AddressException e) {
                e.printStackTrace();
            }
            return null;
        }).collect(Collectors.toList());
    }
  • extracted handling method
    public List<InternetAddress> getListOfInternetEmailAddresses(List<String> toEmails) {
        return toEmails.stream().map(this::createInternetAddress).collect(Collectors.toList());
    }

    private InternetAddress createInternetAddress(String email) {
        try {
            return  new InternetAddress(email);
        } catch (AddressException e) {
            e.printStackTrace();
        }
        return null;
    }
  • generalized extracted handling method
@FunctionalInterface
public interface FunctionThrowing <T, R, E extends Exception> {
    R apply(T var1) throws E;

    static <T, R, E extends Exception> Function<T, R> handled(FunctionThrowing<T, R, E> ft) {
        return result -> {
            try {
                return ft.apply(result);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        };
    }
}
    public List<InternetAddress> getListOfInternetEmailAddresses(List<String> toEmails) {
        List<InternetAddress> internetAddresses = new ArrayList<>();
        internetAddresses = toEmails.stream().map(FunctionThrowing.handled(InternetAddress::new)).collect(Collectors.toList());
        return internetAddresses;
    }
  • Related