Monday, April 10, 2023

Java 8 Optional isPresent(), OrElse() and get() Examples

The Optional class in Java is one of many goodies we have got from the Java 8 release. If you use it correctly, Optional can result in clean code and can also help you to avoid NullPointerException which has bothered Java developers 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 a field or variable from a null object but how does that null is get created on the code is unknown.

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

The biggest benefit of using the 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 indicates that a value may be present.

You just need to take the literal meaning of Optional that value may or may not be present and you have to code accordingly. This will think you what to do in case of value is not present like using a default value or throwing a proper error message.

On a related note,  Java is moving really fast and we are already in Java 12, still, a lot of developers have to learn Java 8, particularly the functional programming aspect. If you think that your Java 8 skills are not at par or you want to improve yourself, I suggest you join a comprehensive Java course like The Complete Java MasterClass. It covers everything you need to know and also recently updated for Java 11.




How to use Optional in Java 8

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 that takes a letter and returns 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 check out From Collections to Streams in Java 8 Using Lambda Expressions course on Pluralsight. It's one of the best courses on Collection and Stream and I highly recommend all Java developers to take a look at it.

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




Modified Java Program using Optional Object

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. This is the most important benefit of using Optional, it forces developers to code accordingly. 

We have also used the new Stream API to convert our imperative style code to the 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 returns value or null.

Anyway, by using the 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 the OrElse() method is much nicer than the combination of isPresent() and get(). It not only removes the check but also more expressive like either return a book or else a specified String.

The Optional API is also rich and provides 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 further see The Complete Java MasterClass on Udemy to learn about Java API and the modern way of Java Coding.

Java 8 Optional Example




Java Program Using Optional Features of Java 8

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()




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 Haskell'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.


Related Java 8 Tutorials
If you are interested in learning more about the 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)
  • Java 8 Stream.findFirst() + filter() example (see)
  • How to convert List to Map in Java 8 (solution)
  • How to join String in Java 8 (example)
  • Difference between abstract class and interface in Java 8? (answer)
  • 10 Free Courses for Experienced Java Programmers (courses)
  • How to use peek() method in Java 8 (example)
  • How to use Stream class in Java 8 (tutorial)
  • How to use forEach() method in Java 8 (example)
  • What is the 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 use peek() method in Java 8 (example)
  • How to sort the may by values in Java 8? (example)
  • How to format/parse the date with LocalDateTime in Java 8? (tutorial)
  • 5 Free Courses to learn Java 8 and 9 (courses)

Thanks for reading this article so far. If you like this tutorial then please share it with your friends and colleagues. If you have any questions or feedback then please drop a note.

P.S.: If you want to learn more about new features in Java 8 then please see the Java Programming, Lambda, and more (Java 13, 12, 11, 10, 9,8), a free course on Udemy. It explains all the important features of Java 8 like lambda expressions, streams, functional interface, Optional, new Date Time API, and other miscellaneous changes from recent Java releases. 

4 comments:

Feel free to comment, ask questions if you have any doubt.