Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to get Different Optional type of Object from CompletableFuture

I have one code snippet, which is calling 2 different services based on some a if condition. And both the services return CompletableFuture<Optional<SomeObject>>. Following is the code logic looks like

if(someCondition){
  CompletableFuture<Optional<SomeObjectType1>> = service1.call();
}else{
  CompletableFuture<Optional<SomeObjectType2>> = service2.call();
}

And both SomeObjectType1 and SomeObjectType2 have a String inside it, which is of my interest. My current code looks like this:

private ContentWrapper getContentWrapper(input1, input2, ....) {
    String content = null;
    if (some_condition is true) {
        List<Object_Type_1> list = service1.fetchTheCompletableFuture(..... inputs...)
                .join()
                .map(ListOutput::getList)
                .orElse(null);
        if (CollectionUtils.isNotEmpty(list)) {
            content = list.get(0).getContent();
        }
    } else {
        content = service2
                .fetchTheCompletableFuture(..... inputs...)
                .join()
                .map(RenderedContent::getContent)
                .orElse(null);
    }
    return content != null ? new ContentWrapper(content) : null;
}

Now my question is, can this if-else clause be removed or make it more clear by using lambdas. I am new in lambdas and does not have very good idea on this.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

I am not sure whether the code below even compiles due to the vagueness.

private ContentWrapper getContentWrapper(input1, input2, ....) {
    Optional<RenderedContent> content = some_condition
        ? service1
                .fetchTheCompletableFuture(..... inputs...)
                .join()
                .map(ListOutput::getList)
                .stream()
                .findFirst()
        : service2
                .fetchTheCompletableFuture(..... inputs...)
                .join();
    }
    return content
                .map(RenderedContent::getContent)
                .map(ContentWrapper::new).orElse(null);
}
  • The first service seems to yield a list of RenderedContent of which to take the first if there is one.
  • The second service may yield a Rendered content immediately.

So you can join the if-else to an Optional<RenderedContent>.
The map(RenderedContent::getContent) will yield Optional.empty() if it was empty to begin with. Otherwise getContent is called and wrapped in an Optional.
If present new ContentWrapper(...) might be called.

Notice much may fail, like getContent returning null (though there is an Optional.ofNullable.

Nevertheless Streams may be very expressive.

I would avoid using null in favor of Optional as that plays better together.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading