1

I am working on a program that consumes methods which return Optional and I need to iterate over that and create a new object. How do I do that?

import java.util.Optional;

class Info {
    String name;
    String profileId;

    Info(String name, String profileId) {
        this.name = name;
        this.profileId = profileId;
    }
}

class Profile {
    String profileId;
    String profileName;

    Profile(String profileId, String profileName) {
        this.profileId = profileId;
        this.profileName = profileName;
    }
}

class Content {
    String infoName;
    String profileName;

    Content(String infoName, String profileName) {
        this.infoName = infoName;
        this.profileName = profileName;
    }

    public java.lang.String toString() {
        return "Content{" + "infoName='" + infoName + '\'' + ", profileName='" + profileName + '\'' + '}';
    }
}

class InfoService {
    Optional<Info> findByName(String name){ //todo implementation }
}

class ProfileService {
   Optional<Profile> findById(String id) { //todo implementation }
}

class ContentService {

    Content createContent(Info i, Profile p) {
        return new Content(i.name, p.profileName);
    }

    Content createContent(Info i) {
        return new Content(i.name, null);
    }
}

public static void main(String[] args) {

    InfoService infoService = new InfoService();
    ProfileService profileService = new ProfileService();
    ContentService contentService = new ContentService();

    //setup
    Info i = new Info("info1", "p1");
    Profile p = new Profile("p1", "profile1");

    // TODO: the following part needs to be corrected
    Optional<Info> info = infoService.findByName("info1");

    if (!info.isPresent()) {
        return Optional.empty();
    } else {
         Optional<Profile> profile = profileService.findById(info.get().profileId);

         Content content;

         if (!profile.isPresent()) {
             content = contentService.createContent(info);
         } else {
             content = contentService.createContent(info, profile);
         }

        System.out.println(content);
     }
}

My understanding of the Java Optional is to reduce the if null checks but I still can't do it without the if checks. Is there a better solution to use map or flatMap and have a concise code?

4
  • there is an if else contradiction in return types. Commented Nov 14, 2018 at 13:05
  • The simplicity of the question doesn't match the complexity of your example. Please rephrase (if it's indeed a complex problem) or simplify the example to an MCVE Commented Nov 14, 2018 at 13:08
  • @nullpointer can you explain what you mean? This code is a re-write of what I am doing (I don't want to use the same Models used in the company codebase) Commented Nov 14, 2018 at 13:08
  • 1
    if (!info.isPresent()) { return Optional.empty(); } I meant this part specifically within a void method, Commented Nov 14, 2018 at 13:11

1 Answer 1

8

This is the about the best you can get. map will only execute the lambda if it's present. orElseGet will only execute the lambda if it's not.

return infoService.findByName("info1")
    .map(info ->
        profileService.findById(info.profileId)
            .map(profile -> contentService.createContent(info, profile))
            .orElseGet(() -> contentService.createContent(info))
    );
Sign up to request clarification or add additional context in comments.

2 Comments

Nice one, Michael. Is there a way to chain infoService.findByName() at the beginning using map or flatMap to make the code even more concise?
@bak Yeah, just needs another map call. Edited my answer

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.