Optional in Java

Optional:


  • In order to get rid of NullPointerException. Java8 introduced a new class  in the java.util.Optional
  • It is a container object , which value may or may not contain null value.
  • It is a value based class , use of ==, identity hash code, synchronisation, may give unpredictable results and avoided.
  • It is type safe way of dealing with values which might be null.
  • It is elegant way of dealing with nulls in functional code.
  • How we can prevent these null checks?
  • To indicate that a method  can return an actual value or null value, we can wrap the returned object in an Optional.
  • It deals with null value at compile time level rather than at run time level.
  • Runtime exceptions discovered in production become compile time concerns during development.
  • It contains some useful methods as below:

    • public static <T> Optional<T> of(T value)   ——> it can throw null pointer exception if value is null
    • public static <T> Optional<T> ofNullable(T value)—>it returns empty Optional if value is null


Main difference is in usage: 

of—> can throw null pointer exception if value is null

ofNullable—> does not throws null pointer exception but gives empty optional object.


  1. public T get()—> can throw NoSuchElementException if value is not present.
  2. public boolean isPresent() —> true=if value is present, false= if value is null
  3. public T orElse(T other)—> if value present returns the value, if value is null, then it can give default value passed in as argument
  4. public T orElseThrow()—> if value present returns value, if value is null throws an exception.


Optional<T>


Before Java8 developers had to carefully validate values because of possible of possibility of Null Pointer Exception (NPE) . All these were needed a error prone boilerplate code.


Optional<T> handles this issue of NPE and provides a predefined actions instead of throwing NPE.


Methods:

1. empty() : returns  empty Optional instance

2. get(): If value present in this optional , returns value otherwise throws NPE   

3. ifPresent() : returns true if value present else false

4. isPresent(Consumer other): if value present invokes specified consumer with value else do nothing

5. of( ): returns optional with non null value otherwise throws NPE

6. ofNullable() returns optional with value if not null otherwise returns empty Optional

7. orElse(T other) returns the value if present otherwise return other

8. orElseGet(Supplier other) return the value if present otherwise invokes other and returns NPE

9. OrElseThrow(Supplier exception) returns value if present otherwise exception is thrown 



Creation of Optional:


   1. Optional<String> optional = Optional.empty();

            - It returns an empty Optional 


   2.  String s = “sumit”;

        Optional<String> optional = Optional.of(s);

            - Returns an optional which contains non null value


     3. Optional<String> optional = Optional.ofNullable(getValue());

            - It returns Optional with a specific value or empty Optional if parameter is null


Usages:


eg1: 

  

  Before: 

   List<String> list = getList();

   List<String> listString = list!= null? list: new ArrayList<>();


  Using Java8

    List<String> listString = getList().orElseGet( ()-> new ArrayList<>());


eg2:



Before:

 User user = getUser();

if (user != null) {

    Address address = user.getAddress();

    if (address != null) {

        String street = address.getStreet();

        if (street != null) {

            return street;

        }

    }

}

return "not specified";


  Using Java8


 Optional<User> user = Optional.ofNullable(getUser());

  

 String result = user.map(User::getAddress)

     .map(Address::getStreet)

     .orElse("not specified");


Here we used map() methods to convert results to Optional<Address> and Optional<User>, here any of these methods return null then map() would return an empty Optional.


if getters of getAddress() and getStreet() return Optional<T> then we should use flatMap


eg3: Optional.orElseThrow()


String value = null;

Optional<String> valueOpt = Optional.ofNullable(value);

String result = valueOpt.orElseThrow(CustomException::new).toUpperCase();



Optional.ifPresentOrElse()


if (shoppingBasket.isPresent()) {

   displayShoppingBasketContent(shoppingBasket.get());

} else {

   displayEmptyShoppingBasket();

}


shoppingBasket.ifPresentOrElse(this::displayShoppingBasketContent, this::displayEmptyShoppingBasket);


Optional.or()


Optional<ShoppingBasket> shoppingBasket = findShoppingBasket().or(

() -> Optional.of(new ShoppingBasket("empty shopping basket")));


If value is present, method will return Optional describing the value, otherwise returns an Optional produced by the supplying function:


Mapping Optional Values:


We can map an optional value with map


eg1:

Optional<string> message = Optional.of(“message”);

Optional<string> oCapital = message.map(s->s.toUpperCase());

String value = oCapital.ge(); // MESSSAGE o/p


eg2:

Optional<Person> op = Optional.of(“”);

Optional<Integer>  oAge = op.map(p->p.getAge());



eg3:

Optional<Person> oPerson = Optional.of(new Person(“John”, 35));


boolean isMiddleAge = oPerson.map(p->Person::getAge())

.filter(age -> age>= 13)

.filter(age<= 35)

.isPresent();







Comments

Popular posts from this blog

Apache Spark

Streams In Java8