Java 8 Optional Example - isPresent(), OrElse() and get()

The Optional class in Java is one of many goodies we have got from the Java 8 release. If you use correctly, Optional can result in clean code and can also help you to avoid NullPointerException which has bothered Java developer from its inception. Even though many of us have used null to indicate the absence of something, the big problem is that if you call a method or access a field on the null object (except static fields), you will get a NullPointerException and your whole program may crash. The bigger problem is to find the faulty code or root cause because NullPointerException only indicates the line when you try to access field or variable from a null object but how does that null is get created on the code is unknown.

I have seen many developer spending nights finding the source of dreaded NullPointerException. Thankfully some of those problems can be resolved by correctly using Optional class.

The biggest benefit of using Optional class is that it improves the readability of code. Now, you don't need to guess whether a value is present or not. Optional itself indicate that a value may be present.

Optional is nothing but a container, you can also view it as a Stream of one or none values. Now, let's see some examples of Optional class to write clean code in Java.

Suppose, we need to write a method which takes a letter and return the first book starting with that letter in the library. If there is no book found for that letter we return null.



package tool;

import java.util.Arrays;
import java.util.List;

/**
 * Program to demonstrate how to use Optional in Java 8 
 * 
 * @author WINDOWS 8
 *
 */
public class Hello {
  private static List<String> listOfBooks = Arrays.asList("Effective Java",
      "Clean Code", "Test Driven");

  /*
   * Return the first book start with a letter.
   */
  public static String getBook(String letter) {
    String found = null;
    for (String book : listOfBooks) {
      if (book.startsWith(letter)) {
        found = book;
        break;
      }
    }

    return found != null ? found : "Book not Found";
  }
}



You can replace the null check in this method using Optional.get() and Optional.isPresent() method and imperative code with the new Java 8 functional code using Stream API. 

If you are not familiar with Stream API  then check the Javadoc of Java SE 8 or higher version, and if you find Javadoc boring then you can also join Complete Java MasterClass or read Core Java SE 9 for the Impatient (2nd Edition) to learn more about them.

how to use Optional in Java 8


Anyway here is our modified Java program using the Optional feature of Java 8:

package tool;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;

/**
 * Program to demonstrate how to use Optional in Java 8
 * 
 * @author WINDOWS 8
 *
 */
public class Hello {
  private static List<String> listOfBooks = Arrays.asList("Effective Java",
      "Clean Code", "Test Driven");

  /*
   * Return the first book start with a letter.
   */
  public static String getBook(String letter) {
    Optional<String> book 
          = listOfBooks.stream()
                       .filter(b -> b.startsWith(letter))
                       .findFirst();

    return book.isPresent() ? book.get() : "Book Not Found";
  }
}


What we have done here is instead of using String to represent a book, we have used Optional<String> which means the variable may or may not contain a book.

We have also used new Stream API to convert our imperative style code to new Java 8 functional style. Since Stream API returns Optional it makes it easy to explain the example.

Anyway, if you look closely, the new check is not better than the old null check. If you compare, the old one was even shorter and cleaner. So, we are not really using Optional in the right way. That's actually the main problem for Java developers who have not understood the Optional concept fully.

Instead of using ifPresent() and get(), it's better to use OrElse() method which can return a default value if Optional doesn't contain a value. Using plain get() is not an option because it either return value or null.

Anyway, by using orElse() method we can rewrite the above code as shown below, which is much more cleaner and expressive.

/*
   * Return the first book start with a letter.
   */
  public static String getBook(String letter) {
    Optional<String> book 
          = listOfBooks.stream()
                       .filter(b -> b.startsWith(letter))
                       .findFirst();

    return book.orElse("Book Not Found");
  }
You can see that OrElse() method is much nicer than the combination of isPresent() and get(). It not only remove the check but also more expressive e.g. either return a book or else a specified String.

And here is the screenshot of a complete program to use Optional in Java 8  for your reference:


Java 8 Optional Example - isPresent(), OrElse() and get()


The Optional API is also rich and provide a couple of useful methods like ifPresent() and orElseThrow() which can be used to throw an Exception if the value is not present. You can see 10 Examples of Optional in Java 8 to learn more about those methods.

That's all about how to use the Optional class in Java 8. Even though it's a poor cousin of Scala's Option type and Haskel's Maybe type, you can still write cleaner code and avoid NullPointerException if used correctly. Don't just use it blindly otherwise you would end up with poor code, sometimes worse than plain null checks.

Further Reading
What's New in Java 8
The Ultimate Java 8 Tutorial
The Complete Java MasterClass

Related Java 8 Tutorials
If you are interested in learning more about new features of Java 8, here are my earlier articles covering some of the important concepts of Java 8:

  • How to join String in Java 8 (example)
  • How to use filter() method in Java 8 (tutorial)
  • Java 8 - Stream.collect() Example (example)
  • How to use Stream class in Java 8 (tutorial)
  • How to use forEach() method in Java 8 (example)
  • What is double colon operator of Java 8? (tutorial)
  • 20 Examples of Date and Time in Java 8 (tutorial)
  • 5 Books to Learn Java 8 from Scratch (books)
  • How to convert List to Map in Java 8 (solution)
  • How to sort HashMap in Java 8? (example)
  • How to use peek() method in Java 8 (example)
  • Java 8 Stream.findFirst() + filter() example (see)

Thanks for reading this article so far. If you like this Java 8 Optional example then please share with your friends and colleagues. If you have any questions or doubt then please drop a note.

No comments:

Post a Comment