Java 8: Actions on Optional object

Introduction

Optional class was added in Java 8 release under java.util package. For more details about Optional please visit Java 8 Optional page. Optional class has a private constructor so there are different ways of creating optional object. In most of the cases we just need to Check value or access value from optional object. Some times we need to perform some actions on optional object if desired value is present or we need to convert value form one form to another.

Different actions to perform on the java 8 Optional object

  1. Conditional Action With void ifPresent(Consumer<? super T> consumer): 

    Public method that executes only if value is present.
    Without optional we need to check values as,

    if(name != null){

    System.out.println("Hello" +name);

    }

    if(id != null){

    userService.findById(id);

    }

    It is very obvious that this could cause NullPointerException at runtime if we miss to check null value.

    Using optional we can overcome this issue with very clean code.

    Optional optional = Optional.of("stacktraceguru");
    optional.ifPresent( name -> System.out.println( "Hello" +name ) );
    Optional optional = Optional.ofNullable(id);
    optional.ifPresent( id -> userService.findById(id) );

    We can convert our object into Optional object using ofNullable(value) if we don’t have optional object

  2. Transformation using Optional<U> map(Function<? super T, ? extends U> mapper): 

    Public method that allows to transform value from one form to other form using specified logic.
    Most important point to note is that map() returns the new value and does not modify the original value.
    We need to provide mapping logic as argument to convert value.
    Returns the empty optional if value is not present.

    Without optional we need to check values as,

    User person = .....
    if(person!=null)

     

    name = person.getName();

    }

    Using optional we can do this easily

    Optional<User> person = .....
    Optional <String> name = person.map(o -> o.getName());

     

    OR

    Optional <String> name = person.map(User :: getName);

    We can convert our object into Optional object using ofNullable(value) if we don’t have optional object

  3. Transformation using Optional<U> flatMap(Function<? super T, Optional> mapper): 

    Public method that almost similar to map(), The difference is that map transforms values form Optional object and flatMap transforms the nested Optional object(Optional< Optional >).

    Some time while writing some programs it is possible that the Optional value is also Optional so this could lead to Optional< Optional>.

    class Testuser {

    Optional<Integer> id;

    String name;

    Testuser(Integer id, String name) {

    this.id = Optional.ofNullable(id);

    this.name = name;

    }

    //getter methods

    }

    .....

    public static void main(String[] args) {

    Optional<Testuser> optional = Optional.ofNullable( new Testuser(1, "a") );

    System.out.println ( optional );                                        // Optional[package.Testuser @ 45abcd123]

    System.out.println ( optional.map (Testuser::getId) );                  // Optional[ Optional [1] ]

    System.out.println ( optional.flatMap(Testuser::getId) );               // Optional[1]

    System.out.println ( optional.flatMap (Testuser::getName) );        // error-as nested object expected

    }

Most important point to note is the mapper function(login in argument) must return Optional object, we can not user function which does not return optional object.

Fast track reading :

  • Three  major actions can be performed optional object
  • Conditional void ifPresent (Consumer<? super T> consumer): executes the logic only if value is present
  • Transformation using Optional<U> map(Function<? super T, ? extends U> mapper): transform value from one form to other using specified logic in mapper function
  • Transformation using Optional<U> flatMap(Function<? super T, Optional> mapper): transform value from nested Optional object using specified logic in mapper function
  • Return type of Mapper function in flatMap() must be Optional

Leave a Reply

Your email address will not be published. Required fields are marked *