Java 8 optional in detail

When writing programs in java, we often deal with scenarios where we get null reference for objects. Such scenarios are pain for developers, as de-referencing such variables cause, you guessed it, null pointer exceptions. The standard practice, for developers, before Java 8, was to null check every time you faced such ambiguous instances of objects.

String username= userRepository.getUsername(id);
    if (username!= null) {
         log.debug("Username: {} " , username);
        authenticate(username);
      }

Java 8 has added an API to avoid such scenarios where developers de-reference null reference and find themselves in trouble. Through the use of Optional API, Java has minimized the problem of null pointers.

All Major Interfaces of JAVA 8 Optional API are as follows:

static <T> Optional<T>empty()Returns an optional object for which is present is false
boolean equals(Object val)Checks if the object val is equal to the element inside the optional value
Optional<T> filter(Predicate<? extends T> condition)Using Predicate functional interface this filter returns Optional object with value present , only if it matches the condition defined in the predicate.
T get()Gets the value from the optional object. If you get a value and the value is not present it throws a NoElementFoundException
int hashCode()Returns the hashcode of the invoking object , if element not present then returns 0.
void ifPresent(Consumer<? super T> func)Executes a Consumer function that performs a certain action if the data is present in the Optional object.
boolean isPresent()Checks if there is a value present inside the Optional Object
U Optional<U> map(Function<? super T , ? super U> mapFunc)Returns a Optional Object with the mapped value of the elements of type T to a new element of type U.
static <T> Optional<T> of (T t)Returns an Optional Element that wraps an element t if present , and an exception if element t is null.

There are specific implementation of Optional Interface aswell. For instance OptionalInt is an implementation of Optional that handles only Integer values. OptionalLong, OptionalDouble, OptionalBoolean are other similar implementations. Specific implementations of Optional has a few interfaces less than the original Optional Implementation.

How to use the individual interfaces? Here are a few very simple examples about using interfaces in optional. Do look at the definition in the table when you are looking at the example snippet for further clarification.

  1. of() and ofNullable() isPresent()
String str;
 Optional<String> strOpt = Optional.of(str);
 Optional<String> emptyOpt = Optional.ofNullable(null);
//interface provides way to check if a value is present or not
 if(strOpt.isPresent()){
    //opt.get() gives the values inside
     //calling the get() in which value isn't present often results
     //in null reference
     System.out.printf("Value inside optional: %s \n" , strOpt.get() );
 }

2. orElse()

System.out.printf("Printing default value for : %s " ,emptyOpt.orElse("Default value"));

3. filter()

Optional<String> val = strOpt.filter(s -> {
    return s.equalsIgnoreCase("Singapore") ;
 });

Function Interface will filter element if the value of the string element inside optional is singapore.

4. map()

public class StringWrapper {
     String val;
 
    public StringWrapper(String val) {
         this.val = val;
     }
 
     public String getVal() {
         return val;
    }
 
     public void setVal(String val) {
         this.val = val;
     }
 }
Optional<StringWrapper> stringWrapperOptional= strOpt.map(s -> new StringWrapper(s));

Converts the String into StringWrapper and creates a new optional element.

5. elseThrow()

Supplier mySupplier = () -> new Exception("No Element Found ");
 Optional<String> emptyOpt = null; 
 Optional.ofNullable(null);
 emptyOpt.orElseThrow(mySupplier);

6. ifPresent()

//if present then use a Double Consumer interface
//do something with the value - dbOperation maybe
OptionalDouble optionalDouble = OptionalDouble.of(repostiory.stanId());
optionalDouble.ifPresent(value - > {
    System.out.printf("Printing value if present: %f \n", value);
});

Calls the consumer interface to perform the system.out if value is present in optionalDouble.

Conclusion: Optional is a nice way to avoid null pointer exceptions in java version 8 and later. Making proper use of optional helps developers avoid null pointer exceptions.