Better code in Java using VAVR

Pramuditya Ananta Nur
5 min readDec 5, 2021
https://github.com/vavr-io/vavr

Introduction

VAVR (previously known as java slang) is a library created by Daniel Dietrich and Robert Winkler that provides functionality to create immutable data types and an API to control its functionality. In addition, Vavr offers an API to facilitate the use of functional programming in Java. It should be noted that Vavr does not contain any dependencies with external libraries and is only built on the Java API.

https://docs.vavr.io/

In the tree hierarchy above, there are various types of data offered, from monads, collections, to functions. I will not explain them all, but I will explain the important and useful points to make the code more clean, short, and robust.

Monad

A Monad is a container for data that allows you to perform operations declaratively on that data and can use common operations to other monads.

  • Option
    The Monad Option in Vavr is almost the same in functionality as optional in Java. Monad is used to express when we call a method that returns a result or returns no result at all. The main difference between option and optional is that when the mapping function returns null it will throw an exception.
monad — option

In the example above, the optional java will throw an exception, while the Vavr will return the value None.

monad — option
  • Tuple
    Monad Tuple is used to store multiple data types at once. Tuple in Vavr can accommodate up to 8 types of data types. Index in tuple starts from 1 and not from 0.
  • Either
    Monad Either is used to return two types of values Left or Right. The Left value is used to store the value when the operation of the method fails, while the Right value is used to store the value when the operation of the method is successful.

when the method above is executed, it will return the value:

  • Left(Failed) when the input value is 70.
  • Right(90) when the input value is 90.
  • Right(A+) when the input value is 90, filterOrElse is used to filter the value of Right valuations whether it matches the desired criteria. Otherwise, it will be a Left value.
  • Left(A) when the input value is 85, and it doesn’t qualify in the filter, it will return the default value which is A.
monad — either
  • Lazy
    Monad Lazy returns a value not when it’s initialized, but when the value is obtained from calling the monad. This behavior is more or less the same as the supplier in Java. The difference is that the monad implements memoization which means that the value obtained will always be the same. So it’s enough to run the operation once.
monad — lazy

if the method above is executed, it will return the value:

  • false, because the value in the monad has not been executed at initialization.
  • will print a “random executed” log and shows a random value, because the monad value was already called.
  • generates the same random value as the previous line. The difference is that the “random executed” log no longer appears. This is because of the memoization feature that is only executed once, later the value will be stored and used when needed again.
monad — lazy

Collections

Collections in Vavr have the same functionality as those in Java. On the plus side, collections in Vavr provide immutable collections, although they exist in Java as well. The weakness in Java is that we can only do read-only access to these collections when we want to change the internal state. In addition, the collections in Vavr provide lots of APIs to make changes to data.

collection

If the immutability method in Java is executed, it will produce an error because when we create an immutable collection it’s only granted read-only access.
Another example when running the javaList method, the result of items and duplicateItems will be the same, even though the item removed is only from duplicateItems. This is not the case with existing collections in Vavr, where when you make changes to a collection, only those collections will change the state.

collections

Functions

Functions in Vavr are almost the same as those in Java. It can be used for functional programming. It’s just that in Java it’s limited to 1 to 2 parameters, while in Vavr it can be used up to 8 parameters.

when we write the code above, there will be a compile error. It happens because functions in Java can’t accept checked exceptions. With Vavr we can change the code above to be like this (line 3–10).

the code above (line 3–10) will not generate a compile error but will produce a runtime error when the value 0 is executed, i.e. ArithmaticException and the value 3 will not be executed. To avoid this, Vavr provides a lift function, so the line of code looks like this (line 12–17).

The code above (line 12–17) will not produce a compile error or runtime error, because when an exception occurs it will return the default value of -1. In this way, we don’t know if an exception occurs when the method is called from another method. Don’t worry, Vavr also provides a liftTry function so we can tell if the method we’re calling raised an exception and we can handle the exception where we want (line 19–26).

With the functionality and features that Vavr offers, I think using it in a project can make a clean code, easy to read, easy to maintain, and also further increase robustness for applications running on multithreaded.

--

--