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:

Where Next?

Popular Backend topics Top

New
bot
So you want to live-reload Rust - fasterthanli.me. Good morning! It is still 2020, and the world is literally on fire , so I guess we c...
New
New
First poster: bot
This Python script mimics Babbage’s Difference Engine. In Use this Python script to simulate Babbage’s Difference Engine, Python offered...
New
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
mafinar
So I was thinking of trying out Crystal, I had tried it multiple times but left it midway. Now that there’s a book on it and it’s version...
New
jaeyson
Hey! Just a random thought though: Found an article from fudzilla where AI can be a good debugger. How does one integrate something like ...
New
New
mafinar
Hello! Advent of Year 2023 is upon us and like past few years, I’ll be opening threads discussing each year’s problems. Day 1 was today....
New

Other popular topics Top

Devtalk
Reading something? Working on something? Planning something? Changing jobs even!? If you’re up for sharing, please let us know what you’...
1052 21915 398
New
DevotionGeo
I know that -t flag is used along with -i flag for getting an interactive shell. But I cannot digest what the man page for docker run com...
New
PragmaticBookshelf
From finance to artificial intelligence, genetic algorithms are a powerful tool with a wide array of applications. But you don't need an ...
New
AstonJ
There’s a whole world of custom keycaps out there that I didn’t know existed! Check out all of our Keycaps threads here: https://forum....
New
AstonJ
Continuing the discussion from Thinking about learning Crystal, let’s discuss - I was wondering which languages don’t GC - maybe we can c...
New
New
rustkas
Intensively researching Erlang books and additional resources on it, I have found that the topic of using Regular Expressions is either c...
New
New
New
hilfordjames
There appears to have been an update that has changed the terminology for what has previously been known as the Taskbar Overflow - this h...
New