Optional – map() and flatMap() operations

In this lesson, we will cover the map() and flatMap() methods from the Optional class in Java.

  1. public <U> Optional<U> map(Function<? super T,? extends U> mapper)
    Description:
    If a value is present, apply the provided mapping function to it, and if the result is non-null, return an Optional describing the result. Otherwise, return an empty Optional.
  2. public <U> Optional<U> flatMap(Function<? super T,Optional<U> mapper)
    Description:
    If a value is present, apply the provided Optional-bearing mapping function to it, and return that result. Otherwise, return an empty Optional.

1. Using the map() method

This operation transforms the value contained in an Optional, if present, and returns a new Optional of the transformed value. If not present, returns an empty Optional.

Example:

class Test {

  public static void main(String[] args) {
    Optional<String> stringOptional = Optional.ofNullable("value1");

    stringOptional.map(value -> value.concat("234"))
            .ifPresent(System.out::println);
  }
}
Output: value1234

2. Using the flatMap() method

In case when we have nested Optionals (Optional<Optional<String>>), we can use the flatMap() method to flatten the result and get the raw value.

Example:

Let’s create a Student class that will contain one Optional field – address:

class Student {
  private String firstName;
  private String lastName;
  private int grade;
  private Optional<String> address;

  public Student(String firstName, String lastName, int grade) {
    this.firstName = firstName;
    this.lastName = lastName;
    this.grade = grade;
  }

  public void setAddress(Optional<String> address) {
    this.address = address;
  }

  public Optional<String> getAddress() {
    return address;
  }

  public int getGrade() {
    return this.grade;
  }
}


Now, let’s try to get the address value using the regular map() operation:

class Test {

  public static void main(String[] args) {
    Student student = new Student("John", "Smith", 8);
    student.setAddress(Optional.of("5th Avenue, New York"));
    Optional<Student> studentOptional = Optional.ofNullable(student);

    studentOptional
            .filter(s1 -> s1.getGrade() > 7) // returns Optional<Student[fName, lName, grade, Optional<String> address]>
            .map(s1 -> s1.getAddress()) // returns Optional<Optional<String>>
            .ifPresent(item -> System.out.println(item));
  }
}
Output: Optional[5th Avenue, New York]
 
As you can see, the map() method received the Optional<Optional<String>> value as a parameter, and it returned the value of the address field, which is actually an Optional.

So we got the Optional object in the output, not the actual value contained by it.

Now, let’s try with flatMap():

class Test {

  public static void main(String[] args) {
    Student student = new Student("John", "Smith", 8);
    student.setAddress(Optional.of("5th Avenue, New York"));
    Optional<Student> studentOptional = Optional.ofNullable(student);


    studentOptional
            .filter(s1 -> s1.getGrade() > 7) // returns Optional<Student[fName, lName, grade, Optional<String> address]>
            .flatMap(s1 -> s1.getAddress()) // returns Optional<String>
            .ifPresent(item -> System.out.println(item));
  }
}
Output: 5th Avenue, New York
 
We got the actual value in the output since the flatMap() operation flattened/unpacked the Optional parameter.

That was all about the map() and
flatMap() operations from the Optional class in Java. To learn more, check out other tutorials that teach Java Optional.
 
Happy coding!

 

Leave a Reply

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