How can I use Optional to return empty if there is any exception in the code in it?

11,040

Solution 1

Well, the code can certainly be reduced. i.e.

public Optional<String> getUser(final String emailId) {
       return Optional.of(emailId)
                      .filter(email -> email.contains("@"))
                      .map(email -> email.substring(0, email.indexOf("@")));
}

if this method can ever receive a null value then you'd need to change Optional.of(emailId) to Optional.ofNullable(emailId).

As for:

Also, Optional was introduced in Java8 so is there any way the code can be java7 compatible?

Not that I know of. There may be other libraries that have similar functionality to Java's Optional type, so a little bit of research online may get you to the right place.

Solution 2

Maybe you mean something like this :

public Optional<String> getUser(final String emailId) {
    return Optional.ofNullable(emailId)
            .filter(email -> email.contains("@"))
            .map(email -> Optional.of(email.replaceAll("(.*?)@.*", "$1")))
            .orElseGet(Optional::empty);
}

Example

null              ->   Optional.empty
""                ->   Optional.empty
"[email protected]"   ->   abd

As @Aominè mention, there are some unnecessary parts in my solution, you can use this version instead :

public Optional<String> getUser(final String emailId) {
    return Optional.ofNullable(emailId)
            .filter(email -> email.contains("@"))
            .map(email -> email.replaceAll("(.*?)@.*", "$1"));
}
Share:
11,040
Destructor
Author by

Destructor

Updated on July 25, 2022

Comments

  • Destructor
    Destructor almost 2 years

    Pretty new to Optional/Java8 usage and I had a doubt regarding its usage. I have a function in my API which returns a String which can be null or empty. Its similar to finding the id in email like: [email protected] -> abc is o/p.

    Now one way of doing this was:

    public Optional<String> getUser(final String emailId) {
    
            if (TextUtils.isEmpty(emailId)) {
                return Optional.empty();
            }
    
            String userIDSeparator = "@";
            int userNameEndIndex = emailId.indexOf(userIDSeparator);
    
            if (userNameEndIndex == -1) {
                return Optional.empty();
            }
    
            return Optional.of(emailId.substring(0, userNameEndIndex));
    }
    

    I was wondering if there is any neater way of doing this to return an Optional?

    Also, Optional was introduced in Java8 so is there anyway the code can be java7 compatible? I am aware of preprocessors in C not sure if something similar is available.

    Note: I have not compiled this code, so there might be some errors. I wanted the input on Optional.

    Thanks!

    • Youcef Laidani
      Youcef Laidani about 6 years
      What about return !emailId.contains("@") ? Optional.empty() : Optional.of(emailId.replaceAll("(.*?)@", "$1"));
    • Destructor
      Destructor about 6 years
      Thats using ternary instead of if/else right? Wondering if there is any way by using Optional instead of handling them explicitly.?
  • Ousmane D.
    Ousmane D. about 6 years
    if this method should never receive a null value then using Optional.ofNullable would be hiding a bug rather than indicating to the caller there is something wrong.
  • Ousmane D.
    Ousmane D. about 6 years
    You can also, simplify your code to return Optional.ofNullable(emailId) .filter(email -> email.contains("@")).map(email -> email.replaceAll("(.*?)@.*", "$1"));
  • Youcef Laidani
    Youcef Laidani about 6 years
    This is correct @Aominè If I edit my answer It will look like your's! I prefer to delete it instead +1 from me
  • Ousmane D.
    Ousmane D. about 6 years
    please don't. it's a valid answer, just a few corrections to make it better ;).
  • Youcef Laidani
    Youcef Laidani about 6 years
    Ok @Aominè I will not delete it just for your request, Thank you so much
  • Destructor
    Destructor about 6 years
    @YCF_L I see that one of the difference between yours and Aomine answer is the: .orElseGet(Optional::empty);. Will this cause the result to be set to empty Optional? If not done then what happens?
  • Youcef Laidani
    Youcef Laidani about 6 years
    @Destructor I used orElseGet(Optional::empty); because in the map I used Optional.of(email.replaceAll("(.*?)@.*", "$1")) but as Aominè mention this part is not necessary it Just redundant
  • Ousmane D.
    Ousmane D. about 6 years
    @Destructor on top of the redundancy you should only use orElseGet if creating an alternative value is computationally expensive and I really mean computationally expensive.
  • Destructor
    Destructor about 6 years
    @Aominè "computationally expensive" that was really helpful! Made me understand what it does! Thanks a ton, all my doubts are clear.
  • Destructor
    Destructor about 6 years
    @YCF_L Thanks for the explanation. Really helpful.
  • Ousmane D.
    Ousmane D. about 6 years
    @Destructor no probs, glad it helped you out ;)