Vavr (formerly Javaslang) is a functional programming library for Java 8+. Its concepts are very similar to Scala. This means that it makes it possible on a Java project to benefit from a more functional approach and use things like function composition, pattern matching, partial application or currying within Java without having to fully switch to Scala.

Why not use Scala instead?

If switching to Scala is a viable option, then go for it, but for many Java projects, switching to Scala isn't an alternative and for some teams, learning Scala is too steep. It's in these situations that Vavr is a good alternative. As well it offers a smooth transition to functional programming and could lead some to learn Scala more easily.

Features

Immutability and special classes

From the start, Vavr favors immutability and pure functions, which are key in functional programming. Vavr redefines main collection types under interface Iterable. These are of course immutable and offer functional methods to use them instead of implementing similar Java interfaces like what is done in Guava. Standard Java classes are not adapted to immutability and Guava has bypassed the problem by throwing exceptions like these.

public final boolean addAll(int index, Collection<? extends E> newElements) {
    throw new UnsupportedOperationException();
}

Vavr defines the following class tree.
class tree

This is very much like what Scala has done and for the same reasons.

Tuples

It may seem simple, but Java has no Tuple class. Tuples can be useful for not having to define a class for every type of structure. Some may argue that it's wrong to use tuples, but they can come in handy once in a while.

Pattern matching

At last a better switch case ! Scala has this type of pattern matching integrated into the language, but Vavr has had to deal with Java to have the same power. The following pattern matching in Scala

val s = i match {
  case 1 => "one"
  case 2 => "two"
  case _ => "?"
}

would look like this in Vavr

String s = Match(i).of(
    Case($(1), "one"),
    Case($(2), "two"),
    Case($(), "?")
);

It's actually not that bad and still maintains the same level of readability as with Scala. Vavr has had to define special matchers for the first parameter of Case that can allow the matching an instance of a class, a list element, boolean matching and more.

Monads

Vavr defines monads such as Option, Try, Lazy, Either, Option all of which are similar to their Scala counterparts.

Functions

In order to bring functional paradigms to Java, Vavr offers rudimentary function manipulation. These include composition, lifting (for avoiding exceptions), partial application, currying, and memoization.

Check out the docs for a list of all features.

Conclusion

Vavr brings the full power of functional programming to Java. The downside is that it redefines most Java collections, so Vavr collections may pollute code. Vavr offers the possibility to switch back to Java Collection if necessary.

The learning curve is easier than for Scala, which is a totally different language with its own syntax. Java developers should not be too disturbed by this change. Probably the only difficulty is learning functional programming. Vavr is very documented, relatively light but with comprehensive examples.

I've used it in production and most developers who became acquainted with it now love it.