Java Optional & Vavr Option: An essential introduction
Tags: beginners, java, tutorial, programming
Published: 2019-09-10 08:45:55

---
title: Java Optional & Vavr Option: An essential introduction
published: true
description: 
tags: beginners, java, tutorial, programming
canonical_url: https://mednikov.net/the-ultimate-guide-to-java-util-optional-class/
cover_image: https://www.mednikov.net/wp-content/uploads/2019/09/featured-java_6.jpg
---

Hi there! I would like today to discuss some essential Java topic - usage of Optional class and compare it with an alternative from Vavr library. Optional intitially was introduced in Java 8 and is defined as "a container object which may or may not contain a non-null value". Developers utilize Optionals in order to avoid null checking in places when executing a code leads to not a result, but to _null_ value and it can in its regard results in __NullPointerException__. In such cases, Optional offers us some fancy functionality, but not all of it was introduced in 8th release, some features require Java 11. Another way to handle these issues is Vavr's Option class. 

In this post we would learn how to use Java's Optional class, and then compare it to Vavr's Option class. Note, that code requires at least Java 11 and was tested with Vavr _0.10.2_.

## Introducing Java Optional

The concept of Optional is not something new and has been already implemented in functional programming languages like in Haskell or Scala. It proves to be very useful when modeling cases when a method call could return an unknown value or a value that does not exist (e.g. nulls). Let see how to handle it.

### Creation of Optional

First thing first, we need to obtain an Optional's instance. There are several ways to do it - and moreover we also can create an _empty_ Optional. Check first method - creating from value, it is pretty straightforward:

```java
Optional<Integer> four = Optional.of(Integer.valueOf(4));
if (four.isPresent){
	System.out.println("Hoorayy! We have a value");
} else {
	System.out.println("No value");
}
```

We build an Optional from an Integer value of 4, meaning that there always should be a value and it can not be null, but this is just an example. We check an existence or absence of value with __ifPresent()__ method. You can note, that __four__ is not an Integer, it is a container, _that holds integer inside_. When we sure, that value is inside, we can "unpack" it with __get()__ method. Ironically, if we would use __get()__ without checking, we can end with NoSuchElementException.

Another way to obtain an Optional is using streams. Several [terminal stream's methods](https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html#StreamOps) return Optionals, so we can manipulate them and checking existence or absence, for example:

* findAny
* findFirst
* max
* min
* reduce

Check the code snippet below:

```java
Optional<Car> car = cars.stream().filter(car->car.getId().equalsIgnoreCase(id)).findFirst();
```

Next option is to create Optional from code, that _can potentialy produce null_, e.g. from Nullable:

```java
Optional<Integer> nullable = Optional.ofNullable(client.getRequestData());
```

Finally we can create an _empty_ Optional:

```java
Optional<Integer> nothing = Optional.empty();
```

### How to use Optional

As long as we obtained Optional, we can use it. One of most widespread case is using it in Spring repositories in finding one record by id, so we can build our logic on Optional and avoid null checking (btw, Spring also supports Vavr Options). Let say, we have a book repository and want to find one book.

```java
Optional<Book> book = repository.findOne("some id");
```

First of all, we can execute some logic in case, if book _is presented_. We did it with if-else in the previous section, but we don't need to: Optional provides us a method that accepts a _Consumer_ with object:

```java
repository.findOne("some id").ifPresent(book -> {});
```

or even simplier, we can write it with method references:

```java
repository.findOne("some id").ifPresent(System.out::println);
```

If we don't have a book in repository, we can provide some alternative callback with __ifPresentOrElseGet__ method:

```java
repository.findOne("some id").ifPresentOrElseGet(book->{
	// if value is presented
}, ()->{
	// if value is absent
});
```

Alternatively, we can get another value, if result of operation is not presented:

```java
Book result = repository.findOne("some id").orElse(defaultBook);
```

However with Optionals we need to remember about possible drawbacks. At last example we "guarantee" ourselves that we would obtain a book anyway, either it presents in underlaying repository or comes from __orElse__. But what if this default value is not _constant_, but also requires some complex method? First, Java __anyway__ evaluates __findOne__. Then, it has to process __orElse__ method. Yes, if it is just a default constant value it is ok, but it can be as I said before time-consuming as well.

## Let have an example

Let create a simple example to check how use practically Optional and Option classes. We would have a _CarRepository_ that would find a car based on supplied ID (e.g. on license plate number). Then we would see how to manipulate Optionals and Options.

## Add some code first

Start with POJO class _Car_. It follows _immutable_ pattern, so all fields are final and we have only getters, without setters. All data is supplied during initialization.

```java
public class Car {

    private final String name;
    private final String id;
    private final String color;

    public Car (String name, String id, String color){
        this.name = name;
        this.id = id;
        this.color = color;
    }

    public String getId(){
        return id;
    }

    public String getColor() {
        return color;
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return "Car "+name+" with license id "+id+" and of color "+color;
    }
}
```

Second thing to create is _CarRepository_ class. It would have two options to find car by Id - using old way with possible null result and using Optional like Spring repositories.

```java
public class CarRepository {

    private List<Car> cars;

    public CarRepository(){
       getSomeCars();
    }

    Car findCarById(String id){
        for (Car car: cars){
            if (car.getId().equalsIgnoreCase(id)){
                return car;
            }
        }
        return null;
    }

    Optional<Car> findCarByIdWithOptional(String id){
        return cars.stream().filter(car->car.getId().equalsIgnoreCase(id)).findFirst();
    }

    private void getSomeCars(){
        cars = new ArrayList<>();
        cars.add(new Car("tesla", "1A9 4321", "red"));
        cars.add(new Car("volkswagen", "2B1 1292", "blue"));
        cars.add(new Car("skoda", "5C9 9984", "green"));
        cars.add(new Car("audi", "8E4 4321", "silver"));
        cars.add(new Car("mercedes", "3B4 5555", "black"));
        cars.add(new Car("seat", "6U5 3123", "white"));
    }
}
```

Note, we also populate our repository with some mock cars during initialization, so we don't have any underlaying database. We need to avoid complexities and let concentrate on Optional and Option, not on repositories.

### Finding cars with Java Optional

Create a new test with JUnit (I also have an excellent [tutorial on JUnit 5](https://www.mednikov.net/tutorials/how-to-start-with-unit-testing-in-java-a-quick-introduction-to-junit-5/) if you don't have experience with it). 

```java
@Test
void getCarById(){
    Car car = repository.findCarById("1A9 4321");
    Assertions.assertNotNull(car);
    Car nullCar = repository.findCarById("M 432 KT");
    Assertions.assertThrows(NullPointerException.class, ()->{
        if (nullCar == null){
            throw new NullPointerException();
        }
    });
}
```

This code snippet demonstates the old way. We found a car with Czech license plate __1A9 4321__ and checked that it exists. Then we found a car that is absent as it has Russian license plate and we have only Czech ones in our repository. It is _null_, so it may lead to NullPointerException. 

Next, let move to Java Optionals. First step is to obtain Optional instance from repository using dedicated method that returns Optional:

```java
@Test
void getCarByIdWithOptional(){
    Optional<Car> tesla = repository.findCarByIdWithOptional("1A9 4321");
    tesla.ifPresent(System.out::println);
}
```

In this case we use __findCarByIdWithOptional__ method and then print a car (if it presents). If you run it you would get following output:

```
Car tesla with license id 1A9 4321 and of color red
```

But what if we don't have that special method in our code? In this situation we can obtain Optional from method that potentially could return null value. It is called _nullable_:

```java
Optional<Car> nothing = Optional.ofNullable(repository.findCarById("5T1 0965"));
Assertions.assertThrows(NoSuchElementException.class, ()->{
    Car car = nothing.orElseThrow(()->new NoSuchElementException());
});
```

In this code snippet we use another way. We create Optional from __findCarById__ that can return _null_ if no car was found. We manually use __orElseThrow__ method to throw NoSuchElementException when desired car with license plate __5T1 0965__ is present. An another situation is to use __orElse__ with some default value, if requested data is not available in repository:

```java
Car audi = repository.findCarByIdWithOptional("8E4 4311")
            .orElse(new Car("audi", "1W3 4212", "yellow"));
   if (audi.getColor().equalsIgnoreCase("silver")){
     System.out.println("We have silver audi in garage!");
   } else {
     System.out.println("Sorry, there is no silver audi, but we called you a taxi");
}
```

Ok, we don't have the silver Audi in our garage, so we have to call taxi! 

### Finding cars with Vavr Option

Vavr Option is the another way to handle these tasks. First, install Vavr in your project with dependency management (I use Maven):

```xml
<dependency>
   <groupId>io.vavr</groupId>
   <artifactId>vavr</artifactId>
   <version>0.10.2</version>
</dependency>
```

In a nutshell, Vavr has similar API to create Option instances. We can create Option from nullable:

```java
Option<Car> nothing = Option.of(repository.findCarById("T 543 KK"));
```

Or we can create an _empty_ container with __none__ static method:

```java
Option<Car> nullable = Option.none();
```

Also, there is a way to create Option from Java Optional! Take a look on the code snippet below:

```java
Option<Car> result = Option.ofOptional(repository.findCarByIdWithOptional("5C9 9984"));
```

With Vavr Option we can use same API like with Optional and accomplish aforesaid tasks. For example, we can set a default value in a similar manner:

```java
Option<Car> result = Option.ofOptional(repository.findCarByIdWithOptional("5C9 9984"));
Car skoda = result.getOrElse(new Car("skoda", "5E2 4232", "pink"));
System.out.println(skoda);
```

Or we can thrown an exception, based on an absence of requested data:

```java
Option<Car> nullable = Option.none();
Assertions.assertThrows(NoSuchElementException.class, ()->{
	nullable.getOrElseThrow(()->new NoSuchElementException());
});
```

Alternatively, we can perform an action when data is unavailable:

```java
nullable.onEmpty(()->{
	///runnable
})
```

What if we need to perform an action based on a presence of data, like we did with Optional's __ifPresent__? We can do this with several ways. There is an equal method to __isPresent__ in Optional that in Option is called __isDefined__:

```java
if (result.isDefined()){
	// do something
}
```

However, we use Option to get rid of if-else constructs. Can we float in the same way as with Optional? We can perform operations based on existance with __peek__:

```java
result.peek(val -> System.out.println(val)).onEmpty(() -> System.out.println("Result is missed"));
```

Also, there are some other very useful methods in Vavr Option that gonna make your code much more functional, than with built-in Optional class. So I encourage you to take some time and explore Vavr Option [javadocs](https://static.javadoc.io/io.vavr/vavr/0.9.2/io/vavr/control/Option.html) and experiment with these APIs. I can note some cool things like __map__, __narrow__, __isLazy__ and __when__ that you definetly need to check out. Also, Vavr Option is a part of Vavr family and is heavily integrated with Vavr other classes, and make such comparasion with Optional in vaccuum, e.g. in abscence of such classes is not correct. So, I would also write posts on other Vavr topics, like Try, Collections, Streams. Don't forget to sign up for updates!

## Conclusion

In this post we talked about Optional class in Java. The concept of Optional is not something new and has been already implemented in functional programming languages like in Haskell or Scala. It proves to be very useful when modeling cases when a method call could return an unknown value or a value that does not exist (e.g. nulls). Let see how to handle it. We explored its APIs and did some example finding cars and manipulating results with Optional logic. Then, we discovered an alternative to Optional - Vavr's Option and described its methods as well. 

## Read more

* José Paumard. _Optionals: Patterns and Good Practices_ (2016) Oracle Community Directory, [read here](https://community.oracle.com/docs/DOC-991686)
* Mervyn McCreight and Mehmet Emin Tok. _A look at the Optional datatype in Java and some anti-patterns when using it_ (2019) FreeCodeCamp, [read here](https://www.freecodecamp.org/news/optional-in-java-and-anti-patterns-using-it-7d87038362ba/)
* Radosław Nowak. _Functional programming in Java with Vavr_ (2018) Pragmatists, [read here](https://blog.pragmatists.com/functional-programming-in-java-with-vavr-9861e704301c)