0

I am new to Java 8 and i have a response object which has a list of detail object and the detail object contains a list of reason object where the reason object has a reason code. I am trying to iterate to the reason object from the response object and search if there is any reason code equal to a given key. Could you please help in how to do that in java 8, with minimum complexity. Below is sample way in java 7 not the best approach thou.

 if(response != null && CollectionsUtil.isNotEmpty(response.getDetails())) {

            List<Detail> details = response.getDetails();
            for(Detail det : details) {
                if(CollectionsUtil.isNotEmpty(det.getReasons())) {                  
                    for(Reason reason: det.getReasons()) {
                        if(StringUtils.equalsIgnoreCase("ABC", reason.getReasonCode())) {
                            ///////////call an external method
                        }
                    }

                    }
                }
            }
7
  • 1
    And what does the external method need? Does it need the detail instance? Commented Nov 13, 2018 at 19:38
  • 1
    The tests checking if the collections are empty are useless. Just loop through the collections. If they're empty the loop won't execute, whether or not you test if it's empty. Commented Nov 13, 2018 at 19:38
  • 1
    @JBNizet CollectionUtil.isNotEmpty() might perform a null check. Commented Nov 13, 2018 at 19:51
  • 1
    @daniu If so, the first thing to do would be to fix the design: a collection shouldn't be null, ever. That should be an invariant of the class. Commented Nov 13, 2018 at 19:55
  • 1
    @JBNizet I agree. A check still might have its place though in some cases, eg Jaxb deserialization initializes collection members to null. Commented Nov 13, 2018 at 20:03

1 Answer 1

3

Assuming getReasons() returns a List:

details.stream().
     flatMap(e -> e.getReasons().stream()).
     filter(reason -> StringUtils.equalsIgnoreCase("ABC", reason.getReasonCode())).
     forEach(System.out::println);

Where you would replace System.out::println with the method you wanted to invoke. Also note that I removed the check of CollectionsUtil.isNotEmpty(det.getReasons()), as if the list is empty, it won't make any difference

Sign up to request clarification or add additional context in comments.

4 Comments

I was working on a very similar answer. If OP is just looking to see if there is any matching key to pass along, the filter and forEach could be replaced with a anyMatch call inside the if statement.
May I know the reason to use flatMap? I think map(r->r.getDetails()).map(d->d.getReasons()) also works?
@LunaticJape Yes both ways should work. However flatMap flattens it to a Stream of objects, as opposed to a Stream of Stream of objects
@GBlodgett In this case it should be Stream<List> if I use map instead flatmap, right?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.