2

I have the following code snippet which I would try to change to the lambda function.

if(catList != null && catList.size() > 0) {
    animalType = AnimalType.CAT;
    HttpEntity<List<?>> request = new HttpEntity<>(catList, headers);
    response = restTemplate.postForObject(apiUrl, request, String.class);
} else if(dogList != null && dogList.size() > 0) {
    animalType = AnimalType.DOG;
} else {
    return;
}

Somehow I have written like as shown below, but don't know to incorporate the dogList checking the condition

Optional.of(catList) 
    .map(catList -> {
        ....
    })
    .orElse(return); //<------ THIS IS NOT POSSIBLE

Can anyone please help me with this

4
  • what is the signature of the resource/service method that you're using? Does it expect the various lists and either of them would be null is a must? Commented May 27, 2019 at 14:36
  • @Naman its a void function....I use response later for some other business logic within the same function Commented May 27, 2019 at 14:37
  • Would actually be better if you can update the question with the method and entities that are dealt with in the code segment shared by you. Commented May 27, 2019 at 14:50
  • 2
    stop shoehorning everything into optionals (which btw mostly designed for using as a clearer return type in your api) and lambdas Commented May 27, 2019 at 14:52

2 Answers 2

3

You can have an other Optional inside of the first Optional

Optional o = Optional.of(catList) 
                     .map(catList -> ...)
                     .orElse(Optional.of(dogList)
                                     .map(dogList -> ...));

Or other method using Stream if you can make the call to the service generic enough

Or other method using Stream#of

It will basically go through both lists, find the first that is not null (but you can add other conditions to your filter if you want) and apply the generic call to service.

Optional o = Stream.of(catList, dogList)
                   .filter(Objects::nonNull /*or other condition if you want*/)
                   .findFirst()
                   .map(list -> /*generic call to service*/);

And invoke it this way

if (!o.isPresent()) return;
Sign up to request clarification or add additional context in comments.

8 Comments

Thanks for the reply, but I need to return to branch out of a control flow block and exit the method if both catList or dogList condition is not matching
@AlexMan I modified the answer, I'm afraid it's not possible in a single chain of method invocation
also how do we set the animalType in the second option using Stream.of
@AlexMan By making the method generic. For example, if (list.get(0) instanceof Dog) animalType = AnimalType.DOG;
in that case I think the first option is better right
|
1

It is not possible to exit a method using the Optional or any other class without either explicitly invoking return or throwing an exception. Usage of return inside a lambda expression is understood within the scope of the method implemented of the functional interface, hence there is no chance to do as your shown code.

There are basically two ways to achieve the desired behavior and keep Java language compliance.

  1. Use return after obtaining a definitive result from Optional.

    Here I might repeat an existing answer, but the best you can do is:

    Optional<MyObject> optional = Optional.of(catList) 
        .map(catList -> new HttpEntity<>(catList, headers))
        .map(httpEntity -> restTemplate.postForObject(apiUrl, request, String.class));
    
    if (!optional.isPresent()) { return; }           // here the method execution is terminated
    

    Checking against null or an Null Object might be a way to go as well.

  2. Throw an exception using the Optional::orElseThrow allows the method terminates the method and throws an Exception. Unfortunately, it obliges an upper layer with a need to handle it or rethrow).

    MyObject myObject = Optional.of(catList) 
        .map(catList -> new HttpEntity<>(catList, headers))
        .map(httpEntity -> restTemplate.postForObject(apiUrl, request, String.class))
        .orElseThrow(MyObjectException::new);        // here the method execution is terminated 
    

If the return parameter of the method is not void, the Optional might be used for the return type definition. The null check (or again a Null Object is a way) might be used there is the method called at:

 return Optional.of(catList) 
        .map(catList -> new HttpEntity<>(catList, headers))
        .map(httpEntity -> restTemplate.postForObject(apiUrl, request, String.class))
        .orElse(null);

2 Comments

But how abt the dogList and the animalType
I am trying to create a generic lambda function for handling both catList and dogList instead of duplicating the logic

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.