avatarEmanuel Trandafir

Free AI web copilot to create summaries, insights and extended knowledge, download it at here

6338

Abstract

s="hljs-comment">// will print the color object</span>

Optional<Color> color2 = ColorsRepository.getColor(<span class="hljs-string">"spencer"</span>); System.<span class="hljs-keyword">out</span>.println(color2.orElseThrow(() -> <span class="hljs-keyword">new</span> ColorNotFoundException(<span class="hljs-string">"cannot find color with key = 'spencer'"</span>))); <span class="hljs-comment">// will throw ColorNotFoundException with the given message</span></pre></div><figure id="fc37"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/0*ZVAAH0W9DXkFsd4K"><figcaption>strong start, keep it going.orElse(throwUp) - Photo by <a href="https://unsplash.com/ja/@nigelm23?utm_source=medium&amp;utm_medium=referral">Nigel Msipa</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><h2 id="982e">6. orElse(defaultValue)</h2><p id="0f94">We can specify a default value using the <i>orElse()</i> method of the API. If the <i>Optional is present</i>, the data will be returned. Otherwise, the specified default value will be returned instead:</p><div id="7bc6"><pre>Optional<Color> color1 = ColorsRepository.getColor(<span class="hljs-string">"red"</span>); System.<span class="hljs-keyword">out</span>.println(color1.orElse(Color.WHITE)); <span class="hljs-comment">// will print the RED color object</span>

Optional<Color> color2 = ColorsRepository.getColor(<span class="hljs-string">"spencer"</span>); System.<span class="hljs-keyword">out</span>.println(color2.orElse(Color.WHITE)); <span class="hljs-comment">// will print the WHITE color object</span></pre></div><h2 id="7fd1">7. orElseGet(defaultValueSupplier)</h2><p id="6946">This method is very similar to the previous one. The only difference is that this time, we will provide the default value as a supplier. The benefit of providing a supplier is that the expression will be lazily evaluated.</p><p id="596a">In other words, if the optional <i>is present</i>, the supplier will not be evaluated. This can allow you to avoid creating objects unnecessarily — or even worst, external calls or DB operations. Therefore, the usage of <i>orElseGet </i>is preferred over <i>orElse:</i></p><div id="0849"><pre>Optional<Color> color1 = ColorsRepository.getColor(<span class="hljs-string">"red"</span>); System.<span class="hljs-keyword">out</span>.println(color1.orElse(<span class="hljs-keyword">new</span> Color(<span class="hljs-number">150</span>, <span class="hljs-number">150</span>, <span class="hljs-number">200</span>))); <span class="hljs-comment">// orElse() will create the new Color, but will print the RED Color object</span>

Optional<Color> color2 = ColorsRepository.getColor(<span class="hljs-string">"red"</span>); System.<span class="hljs-keyword">out</span>.println(color2.orElseGet(() -> <span class="hljs-keyword">new</span> Color(<span class="hljs-number">150</span>, <span class="hljs-number">150</span>, <span class="hljs-number">200</span>))); <span class="hljs-comment">// orElseGet() will print the RED Color without creating any other object</span></pre></div><h2 id="ac4c">8. ifPresent(consumer)</h2><p id="a3fe"><i>ifPresent </i>requires an implementation of the <i>Consumer </i>interface as a parameter. If the optional <i>is present</i>, the consumer will be applied, otherwise, it will be ignored:</p><div id="d449"><pre>Optional<Color> color1 = ColorsRepository.getColor(<span class="hljs-string">"red"</span>); color1.ifPresent(color -> System.<span class="hljs-keyword">out</span>.println(<span class="hljs-string">"color retrieved: "</span> + color)); <span class="hljs-comment">// will print the message</span>

Optional<Color> color2 = ColorsRepository.getColor(<span class="hljs-string">"spencer"</span>); color2.ifPresent(color -> System.<span class="hljs-keyword">out</span>.println(<span class="hljs-string">"color retrieved: "</span> + color)); <span class="hljs-comment">// will not do anything</span></pre></div><h2 id="c5f3">9. ifPresentOrElse(consumer, runnable)</h2><p id="9500">Furthermore, we can use <i>ifPresentOrElse </i>if we want to provide a consumer that is going to be applied if the data <i>is present </i>as well as a runnable which runs if the optional <i>is empty</i>:</p><div id="f279"><pre>Optional<Color> color1 = ColorsRepository.getColor(<span class="hljs-string">"red"</span>); color1.ifPresentOrElse( color -> System.<span class="hljs-keyword">out</span>.println(<span class="hljs-string">"color retrieved: "</span> + color), () -> System.<span class="hljs-keyword">out</span>.println(<span class="hljs-string">"color not found"</span>) ); <span class="hljs-comment">// will print color retrieved the message</span>

Optional<Color> color2 = ColorsRepository.getColor(<span class="hljs-string">"red"</span>); color2.ifPresentOrElse( color -> System.<span class="hljs-keyword">out</span>.println(<span class="hljs-string">"color retrieved: "</span> + color), () -> System.<span class="hljs-keyword">out</span>.println(<span class="hljs-string">"color not found"</span>) ); <span class="hljs-comment">// will print "color not found"</span></pre></div><figure id="3313"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/0*rkoN2iBdP9GuWHy0"><figcaption>we are almost there, but here comes the difficult part! — Photo by <a href="https://unsplash.com/@strong18philip?utm_source=medium&amp;utm_medium=referral">Philip Strong</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><h2 id="1a99">10. filter(filterPredicate)</h2><p id="37e0">The <i>filter</i> receives a <i>Predicate</i> implementation and returns another <i>Optional </i>object. There are 3 possible scenarios here:</p><ul><li>if the original Optional object <i>is empty</i>, <i>filter() </i>will return an empty optional as well.</li><li>if the original Optional object <i>is present</i>, the predicate will be evaluated, if it returns ‘<i>false</i>’, then <i>filter() </i>will return an empty optional.</li><li>if the original Optional object <i>is present</i>, the predicate will be evaluated, if it returns ‘<i>true</i>’, an optional wrapping data will be returned.</li></ul><div id="371a"><pre>Optional<Color

Options

> color1 = ColorsRepository.getColor(<span class="hljs-string">"spencer"</span>); color1 = color1.filter(color -> color.getRed() > <span class="hljs-number">100</span>); System.<span class="hljs-keyword">out</span>.println(color1.isPresent()); <span class="hljs-comment">// will print 'false'</span> <span class="hljs-comment">// because the original optional is empty ('spencer' is not a known color name)</span>

Optional<Color> color2 = ColorsRepository.getColor(<span class="hljs-string">"blue"</span>); color2 = color2.filter(color -> color.getRed() > <span class="hljs-number">100</span>); System.<span class="hljs-keyword">out</span>.println(color2.isPresent()); <span class="hljs-comment">// will print 'false'</span> <span class="hljs-comment">// because the Blue Color object has the 'red' value < 100.</span>

Optional<Color> color3 = ColorsRepository.getColor(<span class="hljs-string">"red"</span>); color3 = color3.filter(color -> color.getRed() > <span class="hljs-number">100</span>); System.<span class="hljs-keyword">out</span>.println(color3.isPresent()); <span class="hljs-comment">// will print 'false'</span> <span class="hljs-comment">// because the Red Color object has the 'red' value > 100.</span></pre></div><h2 id="9321">11. map(mappingFunction)</h2><p id="ab67">The <i>map() </i>method receives a function as a parameter and it will apply it to the data if present.</p><p id="9e8a">Finally,<i> map() </i>returns another <i>Optional</i><>, of a different type. For instance, it can convert an <i>Optional<Color></i> to an <i>Optional<Integer></i> if we map a Color to a specific value of the instance:</p><div id="cb58"><pre>Optional<Color> color1 = ColorsRepository.getColor(<span class="hljs-string">"red"</span>); Optional<Integer> redValue1 = color1.map(color -> color.getRed()); <span class="hljs-comment">// will hold the value 255 wrapped into an Optional<> object</span>

Optional<Color> color2 = ColorsRepository.getColor(<span class="hljs-string">"spencer"</span>); Optional<Integer> redValue2 = color2.map(color -> color.getRed()); <span class="hljs-comment">// will be an empty optional</span> <span class="hljs-comment">// because color2 was empty in the first place</span></pre></div><h2 id="3483">12. flatMap(mappingFunction)</h2><p id="2239">We should use <i>flatMap </i>when our mapping function already returns an Optional object. We need to do this to avoid a nested <i>Optional<></i> structure:</p><div id="3123"><pre>Optional<String> colorName = Optional.of(<span class="hljs-string">"red"</span>); Optional<Optional<Color>> color1 = colorName .map(name -> ColorsRepository.getColor(name)); <span class="hljs-comment">//getColor() returns a Optional<Color> </span> <span class="hljs-comment">//therefore, map() will create a nested Optional<> structure</span>

Optional<String> colorName2 = Optional.of(<span class="hljs-string">"red"</span>); Optional<Color> color2 = colorName2 .flatMap(name -> ColorsRepository.getColor(name)); <span class="hljs-comment">//flatMap will perform the map</span> <span class="hljs-comment">//and take care of the nested Optional<> structure</span></pre></div><h2 id="694e">13. Optional.ofNullable(nullableObject)</h2><p id="467b">The static method <i>ofNullable </i>creates an optional based on the data passed in. If the data is <i>null, </i>it will return an <i>empty optional. </i>Otherwise, the optional will be <i>present</i> and it will wrap the data provided.</p><div id="49e4"><pre>Optional<String> optional1 = Optional.ofNullable(<span class="hljs-string">"some random String"</span>); System.<span class="hljs-keyword">out</span>.println(optional1.isPresent()); <span class="hljs-comment">//will print 'true'</span>

Optional<String> optional2 = Optional.ofNullable(<span class="hljs-literal">null</span>); System.<span class="hljs-keyword">out</span>.println(optional2.isPresent()); <span class="hljs-comment">//will print 'false' because optional2 is empty</span></pre></div><h2 id="3089">14. Optional.empty()</h2><p id="a7df">The static <i>empty() </i>method simply creates and returns an empty optiona:</p><div id="4b21"><pre>Optional<String> optional = Optional.empty(); System.<span class="hljs-keyword">out</span>.println(optional.isPresent()); <span class="hljs-comment">//will print 'false'</span></pre></div><h2 id="699f">15. Optional.of()</h2><p id="dd6d">The third and last way of creating an <i>Optional </i>is through the static <i>of() </i>method. This method should only be used for non-null values, otherwise, it will throw a <i>NullPointerException:</i></p><div id="5ff8"><pre>Optional<String> optional1 = Optional.of(<span class="hljs-string">"some random value"</span>); System.<span class="hljs-keyword">out</span>.println(optional1.isPresent()); <span class="hljs-comment">//will print 'true'</span>

Optional<String> optional2 = Optional.of(<span class="hljs-literal">null</span>); <span class="hljs-comment">//will throw a NullPointerException</span></pre></div><figure id="6243"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/0*sIwW5U7MxJGTf6WT"><figcaption>congrats! you’ve made it! the Optional<awardingceremony> is amazing, isn't it?! — Photo by <a href="https://unsplash.com/@floschmaezz?utm_source=medium&amp;utm_medium=referral">Florian Schmetz</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></awardingceremony></figcaption></figure><h1 id="3508">Thank You!</h1><p id="248f">Thanks for reading the article and please let me know what you think! Any feedback is welcome.</p><p id="2c46">If you want to read more about clean code, design, unit testing, functional programming, and many others, make sure to check out <a href="https://readmedium.com/start-here-6d2b065a626">my other articles</a>.</p><p id="f8b2">If you like my content, consider <a href="https://medium.com/@emanueltrandafir">following or subscribing</a> to the email list.</p><p id="f57c">Finally, if you consider becoming a Medium member and supporting my blog, here’s my <a href="https://medium.com/@emanueltrandafir/membership">referral</a>.</p><p id="d499">Happy Coding!</p></article></body>

Each of the 15 Methods of Java Optional’s API Explained in Less than 20 Seconds

Hands-on and beginner-friendly breakdown of Java 8’s Optional API.

Photo by Kenny Eliason on Unsplash

What is “Optional”?

As you may already know, Java 8 introduced some functional features to the language: one of these features is the Optional type.

An Optional object wraps a variable or the return of a function call and, based on this data, it can be in one of the following states:

  • present — if the data it wraps is not null;
  • empty — if it’s used to wrap a null value;

In this article, we’ll briefly explain each method of the Optional class and we’ll use it in a practical example.

2 possible states: the cat can be in the box, or the box can be empty — Photo by Sahand Babali on Unsplash

Code Examples

For the code examples in this article, we’ll use the ColorsRepository class. This class exposes a static method getColor(String colorName) that will return a Color object wrap in an Optional<>.

For example, ColorsRepository.getColor(“red”) will return an Optional object which is present and has the “red” color object inside.

On the other hand, ColorsRepository.getColor(“spencer”) will return with an empty optional, because it doesn’t know about any color with the name “spencer”.

Without further ado, let’s get started.

let’s start! hope you are ready because it’s going to be a long one! — Photo by Braden Collum on Unsplash

1. isPresent()

We can use isPresent() to check the state of the Optional object. This will return true if the Optional is present and false if the Optional wrapper is empty.

Optional<Color> color = ColorsRepository.getColor("red");
if (color.isPresent()) {
    System.out.println("'red' color was found");
}

2. isEmpty()

Similarly, we can check if we’ve wrapped a null value by calling isEmpty(). This method is the opposite of isPresent() and it can be used for more readable code:

Optional<Color> color = ColorsRepository.getColor("spencer");
if (color.isEmpty()) {
    System.out.println("'spencer' color was NOT found");
}

3. get()

get() can be used to access the data inside of an Optional. Be careful though, if the optional is present, this will return the data it wraps — but, if the optional is empty, calling get() will throw a NoSuchElementException.

Optional<Color> color1 = ColorsRepository.getColor("red");
System.out.println(color1.get()); // will print the color object

Optional<Color> color2 = ColorsRepository.getColor("spencer");
System.out.println(color2.get()); // will throw NoSuchElementExceptionjava

4. orElseThrow()

orElseThrow() is doing exactly the same thing as get() — returning the data if present and throwing a NoSuchElementException if empty.

Having the get() method to throw an exception can be a bit counterintuitively. Therefore, with the next java release, the authors have provided another method with the same functionality, but, this time, they made sure the name suggests that an exception will be thrown if the data is missing.

Consequently, the usage of orElseThrow() is preferred over get() — some IDEs or code analyzers may signal this and highlight counterintuitive code.

Optional<Color> color1 = ColorsRepository.getColor("red");
System.out.println(color1.orElseThrow()); // will print the color object

Optional<Color> color2 = ColorsRepository.getColor("spencer");
System.out.println(color2.orElseThrow()); // will throw NoSuchElementException

5. orElseThrow(exceptionSupplier)

The orElseThow(exceptionSupplier) is overloading the method we discussed previously. This time, we can provide our own exception that will be thrown in case the data is missing.

This can be used if we want to throw a custom exception or provide a specific exception message:

Optional<Color> color1 = ColorsRepository.getColor("red");
System.out.println(color1.orElseThrow(() -> new ColorNotFoundException("cannot find color with key = 'red'")));
// will print the color object

Optional<Color> color2 = ColorsRepository.getColor("spencer");
System.out.println(color2.orElseThrow(() -> new ColorNotFoundException("cannot find color with key = 'spencer'")));
// will throw ColorNotFoundException with the given message
strong start, keep it going.orElse(throwUp) - Photo by Nigel Msipa on Unsplash

6. orElse(defaultValue)

We can specify a default value using the orElse() method of the API. If the Optional is present, the data will be returned. Otherwise, the specified default value will be returned instead:

Optional<Color> color1 = ColorsRepository.getColor("red");
System.out.println(color1.orElse(Color.WHITE));
// will print the RED color object

Optional<Color> color2 = ColorsRepository.getColor("spencer");
System.out.println(color2.orElse(Color.WHITE));
// will print the WHITE color object

7. orElseGet(defaultValueSupplier)

This method is very similar to the previous one. The only difference is that this time, we will provide the default value as a supplier. The benefit of providing a supplier is that the expression will be lazily evaluated.

In other words, if the optional is present, the supplier will not be evaluated. This can allow you to avoid creating objects unnecessarily — or even worst, external calls or DB operations. Therefore, the usage of orElseGet is preferred over orElse:

Optional<Color> color1 = ColorsRepository.getColor("red");
System.out.println(color1.orElse(new Color(150, 150, 200)));
// orElse() will create the new Color, but will print the RED Color object

Optional<Color> color2 = ColorsRepository.getColor("red");
System.out.println(color2.orElseGet(() -> new Color(150, 150, 200)));
// orElseGet() will print the RED Color without creating any other object

8. ifPresent(consumer)

ifPresent requires an implementation of the Consumer interface as a parameter. If the optional is present, the consumer will be applied, otherwise, it will be ignored:

Optional<Color> color1 = ColorsRepository.getColor("red");
color1.ifPresent(color -> System.out.println("color retrieved: " + color));
// will print the message

Optional<Color> color2 = ColorsRepository.getColor("spencer");
color2.ifPresent(color -> System.out.println("color retrieved: " + color));
// will not do anything

9. ifPresentOrElse(consumer, runnable)

Furthermore, we can use ifPresentOrElse if we want to provide a consumer that is going to be applied if the data is present as well as a runnable which runs if the optional is empty:

Optional<Color> color1 = ColorsRepository.getColor("red");
color1.ifPresentOrElse(
    color -> System.out.println("color retrieved: " + color),
    () -> System.out.println("color not found")
);
// will print color retrieved the message

Optional<Color> color2 = ColorsRepository.getColor("red");
color2.ifPresentOrElse(
    color -> System.out.println("color retrieved: " + color),
    () -> System.out.println("color not found")
);
// will print "color not found"
we are almost there, but here comes the difficult part! — Photo by Philip Strong on Unsplash

10. filter(filterPredicate)

The filter receives a Predicate implementation and returns another Optional object. There are 3 possible scenarios here:

  • if the original Optional object is empty, filter() will return an empty optional as well.
  • if the original Optional object is present, the predicate will be evaluated, if it returns ‘false’, then filter() will return an empty optional.
  • if the original Optional object is present, the predicate will be evaluated, if it returns ‘true’, an optional wrapping data will be returned.
Optional<Color> color1 = ColorsRepository.getColor("spencer");
color1 = color1.filter(color -> color.getRed() > 100);
System.out.println(color1.isPresent());
// will print 'false'
// because the original optional is empty ('spencer' is not a known color name)

Optional<Color> color2 = ColorsRepository.getColor("blue");
color2 = color2.filter(color -> color.getRed() > 100);
System.out.println(color2.isPresent());
// will print 'false'
// because the Blue Color object has the 'red' value < 100.

Optional<Color> color3 = ColorsRepository.getColor("red");
color3 = color3.filter(color -> color.getRed() > 100);
System.out.println(color3.isPresent());
// will print 'false'
// because the Red Color object has the 'red' value > 100.

11. map(mappingFunction)

The map() method receives a function as a parameter and it will apply it to the data if present.

Finally, map() returns another Optional<>, of a different type. For instance, it can convert an Optional<Color> to an Optional<Integer> if we map a Color to a specific value of the instance:

Optional<Color> color1 = ColorsRepository.getColor("red");
Optional<Integer> redValue1 = color1.map(color -> color.getRed());
// will hold the value 255 wrapped into an Optional<> object

Optional<Color> color2 = ColorsRepository.getColor("spencer");
Optional<Integer> redValue2 = color2.map(color -> color.getRed());
// will be an empty optional
// because color2 was empty in the first place

12. flatMap(mappingFunction)

We should use flatMap when our mapping function already returns an Optional object. We need to do this to avoid a nested Optional<> structure:

Optional<String> colorName = Optional.of("red");
Optional<Optional<Color>> color1 = colorName
      .map(name -> ColorsRepository.getColor(name));
//getColor() returns a Optional<Color> 
//therefore, map() will create a nested Optional<> structure

Optional<String> colorName2 = Optional.of("red");
Optional<Color> color2 = colorName2
     .flatMap(name -> ColorsRepository.getColor(name));
//flatMap will perform the map
//and take care of the nested Optional<> structure

13. Optional.ofNullable(nullableObject)

The static method ofNullable creates an optional based on the data passed in. If the data is null, it will return an empty optional. Otherwise, the optional will be present and it will wrap the data provided.

Optional<String> optional1 = Optional.ofNullable("some random String");
System.out.println(optional1.isPresent());
//will print 'true'

Optional<String> optional2 = Optional.ofNullable(null);
System.out.println(optional2.isPresent());
//will print 'false' because optional2 is empty

14. Optional.empty()

The static empty() method simply creates and returns an empty optiona:

Optional<String> optional = Optional.empty();
System.out.println(optional.isPresent());
//will print 'false'

15. Optional.of()

The third and last way of creating an Optional is through the static of() method. This method should only be used for non-null values, otherwise, it will throw a NullPointerException:

Optional<String> optional1 = Optional.of("some random value");
System.out.println(optional1.isPresent());
//will print 'true'

Optional<String> optional2 = Optional.of(null);
//will throw a NullPointerException
congrats! you’ve made it! the Optional is amazing, isn't it?! — Photo by Florian Schmetz on Unsplash

Thank You!

Thanks for reading the article and please let me know what you think! Any feedback is welcome.

If you want to read more about clean code, design, unit testing, functional programming, and many others, make sure to check out my other articles.

If you like my content, consider following or subscribing to the email list.

Finally, if you consider becoming a Medium member and supporting my blog, here’s my referral.

Happy Coding!

Java
Clean Code
Software Development
Programming
Software Engineering
Recommended from ReadMedium