Intro

Some operations may or may not return anything at all. To deal with this issue, use Optional!

Optional is a wrapper

Optional wraps the result so we can ask if that result is actually present or empty (null).

Optional objects need to be asked if they conain something before you unwrap them. Otherwise, you will get an exception if there is no result.

Optional<IceCream> optional = getIceCream("strawberry")
if(optional.isPresent()){
    IceCream ice = optional.get();
  }

In the past, methods might have thrown Exceptions for this case, or return “null”, or a special type of “Not Found” ice-cream instance. Returning an Optional from a method makes it really clear that anything calling the method needs to check if there’s a result first, and then make their own decision about what to do if there isn’t one.

Optional with Stream

Optional<Song> result = songs.stream()
  .filter(song -> song.getArtist().equals(artist))
  .findFirst();
if(result.isPresent()){
    //unwrap result
    System.out.println(result.get().getTitle());
  }
else{
    System.out.println("no songs");
  }