0
\$\begingroup\$

I have an object delivery template, which I want to delete based on a name. String array which contains delivery template name is taken as an input parameter. I use Java Stream to iterate the list. Please find the code below.

    public static List<String> deleteDeliveryTemplates(String... deliveryTemplateNames) {
    List<String> failureList = new ArrayList<String>();
    Stream<String>deliveryTemplateNamesStream= Stream.of(deliveryTemplateNames);
     deliveryTemplateNamesStream.forEach(deliveryTemplateName ->{
        try
        {
            deleteDeliveryTemplate(deliveryTemplateName);
        } catch (Exception e)
        {
            failureList.add(deliveryTemplateName);
        }
    });
    return failureList;
}

Is there a better way in JAVA 8 to return the failure list using stream. For example: using map function of Stream

\$\endgroup\$
2
\$\begingroup\$

Just because you can do it in streams, that doesn't mean you should. What you really want is the following:

public static List<String> deleteDeliveryTemplates(String... deliveryTemplateNames) {
    List<String> failures = new ArrayList<>();
    for (String templateName : deliveryTemplateNames) {
        try {
            deleteDeliveryTemplate(templateName);
        } catch (Exception e) {
            // LOG THIS EXCEPTION!
            failures.add(templateName);
        }
    }
    return failures;
}

This code is clean, simple, does one thing. Note that I removed the overspecification of generics on the right-hand-side of the failureList declaration and changed the names of your local variables a bit to make use of the surrounding context.

I also slightly reformatted the brace positions in try-blocks to be more in line with the usual Java conventions. As long as you're consistent, there's nothing wrong with your style though.

\$\endgroup\$
  • \$\begingroup\$ Exactly this. I have seen so many people defaulting to streams for absolutely no reason. +1 \$\endgroup\$ – Imus Mar 19 '18 at 9:45
1
\$\begingroup\$

It is somewhat unfortunate for streaming when you base your program flow on exceptions. If you want to attempt the delivery deletion and branch on success-or-not, it would be much better to encapsulate this in a function, which returns a success indicator, e.g.:

private boolean attemptDeleteDelivery(String deliveryTemplateName) {
    try {
         deleteDeliveryTemplate(deliveryTemplateName);
         return true;
    }
    catch(Exception e) {
         // yes, log this!
         return false;
    }
}

With this semantic, you can stream and filter

List<String> failureList
= Stream.of(deliveryTemplateNames)
   .filter(dt -> !attemptDeleteDelivery(dt))
   .collect(Collectors.toList());
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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