Alex Man
Alex Man

Reputation: 4886

Java8 lambda for checking two conditions

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

Upvotes: 2

Views: 1523

Answers (2)

Nikolas
Nikolas

Reputation: 44408

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);

Upvotes: 1

Yassin Hajaj
Yassin Hajaj

Reputation: 21975

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;

Upvotes: 3

Related Questions