finner

finner

Using Optional in Java

During a recent code review I came across this scenario:

Code in review

if (input.getValue() != null) {
   return Arrays.asList(value);
}  else {
   return input.getValues().stream().map(this::parseValues).collect(Collectors.toList())
}

And I suggested (in a compassionate way :grin: ) that we use Optional to treat the null value, so my suggestion was something like:

return Optional.ofNullable(input.getValue()).map(Arrays::asList)
       .orElseGet(input.getValues().stream().map(this::parseValues).collect(Collectors.toList()));

And I thought I was being very clever.

But then I realised it’s harder to understand the logic in this version. At least the if is a clear intent.
So I read up some more on Optional.
The Optional container allows us to perform logic including chaining map, flatMap, filter etc based on a value that may or may not be present. But this is not the real intention of Optional.

Optional is mainly used to represent attributes in an object that may be null or a method in an API that could return a null.

Consider a Person.
Everyone has a name, an age and a gender but may not have a car so we could define a class as follows:

class Person {
   private String name;
   private int age;
   private boolean female;
   private Optional<Car> car;
}

From this declaration it’s obvious that not everyone has a car and so the caller would then treat the car attribute appropriately.

My take away is the following:

Optional is not a replacement for occurrences if (x != null)

Any heavy users of Optional around?
Tips and/or suggestions would be very much appreciated.

Most Liked

finner

finner

Today I came across a very elegant use (IMHO) of Optional at work.
Consider the same person as above with a date of birth attribute:

public class Person {
   private String name;
   private String dob;

   // getters & setters etc etc (yep Java is verbose !!!!)
}

Now say you want to get that dob value into a Date object and do weird and wonderful date calculations.
You could use Optional like this:


// if you expect dob to be a string in the format yyyy-mm-dd
LocalDate birthday = Optional.ofNullable(persone.getDob())
    .map(LocalDate::parse)
    .orElse(null);  // or whatever

// or if the dob is in a different format, for example dd-MM-yyyy
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy");
LocalDate  d = Optional.ofNullable(p.getDob())
                .map(dob -> LocalDate.parse(dob, formatter))
                .orElse(null);

Now you have a LocalDate instance to play with.

In fact, once you have an Optional instance you have the following stream operators available

  • map
  • flatMap
  • filter

flatMap can be used to compose Optionals

public int ageDifference(Optional<Person> older, Optional<Person> younger) {
     return older.flatMap(o -> younger.map(y -> calAgeDifference(o.getDob(), y.getDob())); 
}

Quite cool :sunglasses:

Just thought I’d share :slight_smile:

finner

finner

cheers @AstonJ -
it’s actually good practice for me to help reinforce the learning by posting. Although at my age I will have forgotten it by end of week.
… so what were we talking about again … ?

AstonJ

AstonJ

:rofl: :rofl: :rofl:

I am just as bad - though I think a modern world is partly to blame - we are bombarded with information almost constantly now, imagine living a few thousand years ago before TV/Radio/Computers/Internet. Probably would have been quite serene and peaceful :smiley:

Funny thing is I read that article… and forgot most of it :rofl:

Popular Backend topics Top

DevotionGeo
Some time ago I read somewhere that Rocket will work with stable versions of Rust. The previous version’s changelog says, “Core: Removed...
New
bot
Announcing the Error Handling Project Group | Inside Rust Blog. Want to follow along with Rust development? Curious how you might get in...
New
New
First poster: bot
The Complete AWS Lambda Handbook for Beginners (Part 1). In the first part of our Complete AWS Lambda Handbook for Beginners, we explain...
New
finner
Just wondering how many devs out there are using Spring Reactive, specifically WebFlux?
New
New
First poster: bot
Welcome to RETRO, my personal take on the Forth language. This is a modern system primarily targetting desktop, mobile, and servers, th...
New
kelvinst
I have being some Elixir open-source contributions and side projects. Oh, and I’m doing them on livestreams on my twitch channel, follow ...
New
AstonJ
And the blog: Rails has been unapologetically full stack since the beginning. We’ve continuously sought to include ever-more default an...
New
jaeyson
Hi all!, anybody tried this Elixir quiz from @Tetiana? She’s the one who made Elixircards.
New

Other popular topics Top

wolf4earth
@AstonJ prompted me to open this topic after I mentioned in the lockdown thread how I started to do a lot more for my fitness. https://f...
New
PragmaticBookshelf
A PragProg Hero’s Journey with Brian P. Hogan @bphogan Have you ever worried that your only legacy will be in the form of legacy...
New
siddhant3030
I’m thinking of buying a monitor that I can rotate to use as a vertical monitor? Also, I want to know if someone is using it for program...
New
brentjanderson
Bought the Moonlander mechanical keyboard. Cherry Brown MX switches. Arms and wrists have been hurting enough that it’s time I did someth...
New
Exadra37
On modern versions of macOS, you simply can’t power on your computer, launch a text editor or eBook reader, and write or read, without a ...
New
AstonJ
Just done a fresh install of macOS Big Sur and on installing Erlang I am getting: asdf install erlang 23.1.2 Configure failed. checking ...
New
AstonJ
Inspired by this post from @Carter, which languages, frameworks or other tech or tools do you think is killing it right now? :upside_down...
New
AstonJ
In case anyone else is wondering why Ruby 3 doesn’t show when you do asdf list-all ruby :man_facepalming: do this first: asdf plugin-upd...
New
husaindevelop
Inside our android webview app, we are trying to paste the copied content from another app eg (notes) using navigator.clipboard.readtext ...
New
PragmaticBookshelf
A Ruby-Centric Chat with Noel Rappin @noelrappin Once you start noodling around with Ruby you quickly figure out, as Noel Rappi...
New